mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-06-11 10:34:18 +00:00
Merge tag 'v1.90.1' into tod
Tag 1.90.1
This commit is contained in:
+1
-22
@@ -1,24 +1,3 @@
|
|||||||
ltmain.sh
|
|
||||||
missing
|
|
||||||
stamp-h1
|
|
||||||
libtool
|
|
||||||
*.la
|
|
||||||
*.lo
|
|
||||||
*.o
|
*.o
|
||||||
*.swp
|
*.swp
|
||||||
Makefile
|
_build
|
||||||
Makefile.in
|
|
||||||
config.h*
|
|
||||||
aclocal.m4
|
|
||||||
autom4te.cache
|
|
||||||
config.guess
|
|
||||||
config.log
|
|
||||||
config.status
|
|
||||||
config.sub
|
|
||||||
configure
|
|
||||||
depcomp
|
|
||||||
install-sh
|
|
||||||
.deps
|
|
||||||
.libs
|
|
||||||
compile
|
|
||||||
ChangeLog
|
|
||||||
|
|||||||
+11
-33
@@ -1,15 +1,17 @@
|
|||||||
|
include:
|
||||||
|
- local: '.gitlab-ci/libfprint-templates.yaml'
|
||||||
|
- project: 'wayland/ci-templates'
|
||||||
|
ref: master
|
||||||
|
file: '/templates/fedora.yml'
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
|
extends: .libfprint_common_variables
|
||||||
FEDORA_TAG: rawhide
|
FEDORA_TAG: rawhide
|
||||||
FEDORA_VERSION: rawhide
|
FEDORA_VERSION: rawhide
|
||||||
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FEDORA_VERSION:$FEDORA_TAG"
|
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FEDORA_VERSION:$FEDORA_TAG"
|
||||||
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
||||||
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
||||||
|
|
||||||
include:
|
|
||||||
- project: 'wayland/ci-templates'
|
|
||||||
ref: master
|
|
||||||
file: '/templates/fedora.yml'
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- check-source
|
- check-source
|
||||||
- build
|
- build
|
||||||
@@ -106,9 +108,6 @@ test_indent:
|
|||||||
.flatpak_master_template: &flatpak_master
|
.flatpak_master_template: &flatpak_master
|
||||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32
|
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32
|
||||||
stage: flatpack
|
stage: flatpack
|
||||||
except:
|
|
||||||
variables:
|
|
||||||
- $CI_PIPELINE_SOURCE == "schedule"
|
|
||||||
variables:
|
variables:
|
||||||
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
|
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
|
||||||
# From demo/org.freedesktop.libfprint.Demo.json
|
# From demo/org.freedesktop.libfprint.Demo.json
|
||||||
@@ -128,8 +127,11 @@ flatpak-manual master:
|
|||||||
<<: *flatpak_master
|
<<: *flatpak_master
|
||||||
when: manual
|
when: manual
|
||||||
except:
|
except:
|
||||||
|
refs:
|
||||||
- tags
|
- tags
|
||||||
- master
|
- master
|
||||||
|
variables:
|
||||||
|
- $CI_PIPELINE_SOURCE == "schedule"
|
||||||
|
|
||||||
# CONTAINERS creation stage
|
# CONTAINERS creation stage
|
||||||
container_fedora_build:
|
container_fedora_build:
|
||||||
@@ -140,28 +142,4 @@ container_fedora_build:
|
|||||||
variables:
|
variables:
|
||||||
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||||
# a list of packages to install
|
# a list of packages to install
|
||||||
FEDORA_RPMS:
|
FEDORA_RPMS: $LIBFPRINT_DEPENDENCIES
|
||||||
doxygen
|
|
||||||
flatpak-builder
|
|
||||||
gcc
|
|
||||||
gcc-c++
|
|
||||||
gcovr
|
|
||||||
git
|
|
||||||
glib2-devel
|
|
||||||
glibc-devel
|
|
||||||
gobject-introspection-devel
|
|
||||||
gtk-doc
|
|
||||||
gtk3-devel
|
|
||||||
libabigail
|
|
||||||
libgusb-devel
|
|
||||||
libX11-devel
|
|
||||||
libXv-devel
|
|
||||||
meson
|
|
||||||
nss-devel
|
|
||||||
pixman-devel
|
|
||||||
python3-cairo
|
|
||||||
python3-gobject
|
|
||||||
systemd
|
|
||||||
umockdev
|
|
||||||
uncrustify
|
|
||||||
valgrind
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
.libfprint_common_variables:
|
||||||
|
LIBFPRINT_DEPENDENCIES:
|
||||||
|
doxygen
|
||||||
|
flatpak-builder
|
||||||
|
gcc
|
||||||
|
gcc-c++
|
||||||
|
gcovr
|
||||||
|
git
|
||||||
|
glib2-devel
|
||||||
|
glibc-devel
|
||||||
|
gobject-introspection-devel
|
||||||
|
gtk-doc
|
||||||
|
gtk3-devel
|
||||||
|
libabigail
|
||||||
|
libgusb-devel
|
||||||
|
libX11-devel
|
||||||
|
libXv-devel
|
||||||
|
meson
|
||||||
|
nss-devel
|
||||||
|
pixman-devel
|
||||||
|
python3-cairo
|
||||||
|
python3-gobject
|
||||||
|
systemd
|
||||||
|
umockdev
|
||||||
|
uncrustify
|
||||||
|
valgrind
|
||||||
@@ -1,6 +1,41 @@
|
|||||||
This file lists notable changes in each release. For the full history of all
|
This file lists notable changes in each release. For the full history of all
|
||||||
changes, see ChangeLog.
|
changes, see ChangeLog.
|
||||||
|
|
||||||
|
2019-11-20: v1.90.1 release
|
||||||
|
|
||||||
|
This release fixes a lot of the regressions introduced in 1.90.0. Please note
|
||||||
|
that both the driver and external APIs have changed, as both the verify and
|
||||||
|
the identify functions now have early reporting mechanisms.
|
||||||
|
The soname for the library, as well as a number of file locations have also
|
||||||
|
changed. While this allows installation in parallel with the 1.0 version of
|
||||||
|
libfprint, we recommend installing only one, and migrating from version 1.0 to
|
||||||
|
version 2.0 alongside its main consumer (fprintd).
|
||||||
|
|
||||||
|
Only major changes are listed below. A lot of other cleanup work and small
|
||||||
|
fixes have also been merged.
|
||||||
|
|
||||||
|
* Library:
|
||||||
|
- Add support to run tests in gdb/valgrind
|
||||||
|
- Allow testing on all architectures
|
||||||
|
- Avoid image device AWAIT_FINGER_ON to deactivate state transitions
|
||||||
|
- Fix verify/identify error propagation to library user
|
||||||
|
- Correctly read image device information from class data
|
||||||
|
- Continue enroll after an image driver reported a retry error
|
||||||
|
- Change external API to allow reporting match results early
|
||||||
|
- A lot of new unit tests and integration tests have been added
|
||||||
|
|
||||||
|
* Drivers API
|
||||||
|
- Support variadic arguments in error functions
|
||||||
|
- Various re-definitions of ownership handling
|
||||||
|
- Add convenience API to change state after a timeout
|
||||||
|
- Add unit tests for all the drivers API
|
||||||
|
|
||||||
|
* Drivers:
|
||||||
|
- elan: Ensure correct deactivation of device
|
||||||
|
- uru4000: Fix IRQ handler registration and internal state handling
|
||||||
|
- uru4000: Fix control transfer request type
|
||||||
|
- synaptics: Ensure errors are only reported after finger removal
|
||||||
|
|
||||||
2019-11-20: v1.90.0 release
|
2019-11-20: v1.90.0 release
|
||||||
|
|
||||||
This release updates the core of the library to use GLib routines and Gio
|
This release updates the core of the library to use GLib routines and Gio
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ FpDeviceError
|
|||||||
fp_device_retry_quark
|
fp_device_retry_quark
|
||||||
fp_device_error_quark
|
fp_device_error_quark
|
||||||
FpEnrollProgress
|
FpEnrollProgress
|
||||||
|
FpMatchCb
|
||||||
fp_device_get_driver
|
fp_device_get_driver
|
||||||
fp_device_get_device_id
|
fp_device_get_device_id
|
||||||
fp_device_get_name
|
fp_device_get_name
|
||||||
@@ -159,6 +160,8 @@ fpi_device_identify_complete
|
|||||||
fpi_device_capture_complete
|
fpi_device_capture_complete
|
||||||
fpi_device_delete_complete
|
fpi_device_delete_complete
|
||||||
fpi_device_enroll_progress
|
fpi_device_enroll_progress
|
||||||
|
fpi_device_verify_report
|
||||||
|
fpi_device_identify_report
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
|
|||||||
+2
-5
@@ -23,16 +23,13 @@ glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix')
|
|||||||
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
|
glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html')
|
||||||
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
|
docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html')
|
||||||
|
|
||||||
gnome.gtkdoc(meson.project_name(),
|
gnome.gtkdoc(versioned_libname,
|
||||||
main_xml: 'libfprint-docs.xml',
|
main_xml: 'libfprint-docs.xml',
|
||||||
src_dir: join_paths(meson.source_root(), 'libfprint'),
|
src_dir: join_paths(meson.source_root(), 'libfprint'),
|
||||||
dependencies: libfprint_dep,
|
dependencies: libfprint_dep,
|
||||||
content_files: content_files,
|
content_files: content_files,
|
||||||
expand_content_files: expand_content_files,
|
expand_content_files: expand_content_files,
|
||||||
scan_args: [
|
ignore_headers: private_headers,
|
||||||
#'--rebuild-sections',
|
|
||||||
'--ignore-headers=' + ' '.join(private_headers),
|
|
||||||
],
|
|
||||||
fixxref_args: [
|
fixxref_args: [
|
||||||
'--html-dir=@0@'.format(docpath),
|
'--html-dir=@0@'.format(docpath),
|
||||||
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
|
'--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')),
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
ent_conf = configuration_data()
|
ent_conf = configuration_data()
|
||||||
ent_conf.set('PACKAGE', meson.project_name())
|
ent_conf.set('PACKAGE', versioned_libname)
|
||||||
ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/libfprint/libfprint/issues')
|
ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/libfprint/libfprint/issues')
|
||||||
ent_conf.set('PACKAGE_NAME', meson.project_name())
|
ent_conf.set('PACKAGE_NAME', versioned_libname)
|
||||||
ent_conf.set('PACKAGE_STRING', meson.project_name())
|
ent_conf.set('PACKAGE_STRING', versioned_libname)
|
||||||
ent_conf.set('PACKAGE_TARNAME', 'libfprint-' + meson.project_version())
|
ent_conf.set('PACKAGE_TARNAME', 'libfprint-' + meson.project_version())
|
||||||
ent_conf.set('PACKAGE_URL', 'https://fprint.freedesktop.org/')
|
ent_conf.set('PACKAGE_URL', 'https://fprint.freedesktop.org/')
|
||||||
ent_conf.set('PACKAGE_VERSION', meson.project_version())
|
ent_conf.set('PACKAGE_VERSION', meson.project_version())
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FP_COMPONENT "example-enroll"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <libfprint/fprint.h>
|
#include <libfprint/fprint.h>
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FP_COMPONENT "example-mange-prints"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <libfprint/fprint.h>
|
#include <libfprint/fprint.h>
|
||||||
|
|||||||
+4
-2
@@ -19,7 +19,10 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FP_COMPONENT "example-storage"
|
||||||
|
|
||||||
#include <libfprint/fprint.h>
|
#include <libfprint/fprint.h>
|
||||||
|
#include <libfprint/fpi-compat.h>
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -161,8 +164,8 @@ FpPrint *
|
|||||||
print_create_template (FpDevice *dev, FpFinger finger)
|
print_create_template (FpDevice *dev, FpFinger finger)
|
||||||
{
|
{
|
||||||
g_autoptr(GDateTime) datetime = NULL;
|
g_autoptr(GDateTime) datetime = NULL;
|
||||||
|
g_autoptr(GDate) date = NULL;
|
||||||
FpPrint *template = NULL;
|
FpPrint *template = NULL;
|
||||||
GDate *date = NULL;
|
|
||||||
gint year, month, day;
|
gint year, month, day;
|
||||||
|
|
||||||
template = fp_print_new (dev);
|
template = fp_print_new (dev);
|
||||||
@@ -172,7 +175,6 @@ print_create_template (FpDevice *dev, FpFinger finger)
|
|||||||
g_date_time_get_ymd (datetime, &year, &month, &day);
|
g_date_time_get_ymd (datetime, &year, &month, &day);
|
||||||
date = g_date_new_dmy (day, month, year);
|
date = g_date_new_dmy (day, month, year);
|
||||||
fp_print_set_enroll_date (template, date);
|
fp_print_set_enroll_date (template, date);
|
||||||
g_date_free (date);
|
|
||||||
|
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FP_COMPONENT "example-utilities"
|
||||||
|
|
||||||
#include <libfprint/fprint.h>
|
#include <libfprint/fprint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|||||||
+69
-22
@@ -19,6 +19,8 @@
|
|||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FP_COMPONENT "example-verify"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <libfprint/fprint.h>
|
#include <libfprint/fprint.h>
|
||||||
|
|
||||||
@@ -55,6 +57,19 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
g_main_loop_quit (verify_data->loop);
|
g_main_loop_quit (verify_data->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
verify_quit (FpDevice *dev,
|
||||||
|
VerifyData *verify_data)
|
||||||
|
{
|
||||||
|
if (!fp_device_is_open (dev))
|
||||||
|
{
|
||||||
|
g_main_loop_quit (verify_data->loop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed, verify_data);
|
||||||
|
}
|
||||||
|
|
||||||
static void start_verification (FpDevice *dev,
|
static void start_verification (FpDevice *dev,
|
||||||
VerifyData *verify_data);
|
VerifyData *verify_data);
|
||||||
|
|
||||||
@@ -71,23 +86,13 @@ on_verify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
if (!fp_device_verify_finish (dev, res, &match, &print, &error))
|
if (!fp_device_verify_finish (dev, res, &match, &print, &error))
|
||||||
{
|
{
|
||||||
g_warning ("Failed to verify print: %s", error->message);
|
g_warning ("Failed to verify print: %s", error->message);
|
||||||
g_main_loop_quit (verify_data->loop);
|
verify_data->ret_value = EXIT_FAILURE;
|
||||||
|
|
||||||
|
if (error->domain != FP_DEVICE_RETRY)
|
||||||
|
{
|
||||||
|
verify_quit (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print && fp_device_supports_capture (dev) &&
|
|
||||||
print_image_save (print, "verify.pgm"))
|
|
||||||
g_print ("Print image saved as verify.pgm\n");
|
|
||||||
|
|
||||||
if (match)
|
|
||||||
{
|
|
||||||
g_print ("MATCH!\n");
|
|
||||||
verify_data->ret_value = EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_print ("NO MATCH!\n");
|
|
||||||
verify_data->ret_value = EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("Verify again? [Y/n]? ");
|
g_print ("Verify again? [Y/n]? ");
|
||||||
@@ -98,8 +103,48 @@ on_verify_completed (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp_device_close (dev, NULL, (GAsyncReadyCallback) on_device_closed,
|
verify_quit (dev, verify_data);
|
||||||
verify_data);
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_match_cb (FpDevice *dev, FpPrint *match, FpPrint *print,
|
||||||
|
gpointer user_data, GError *error)
|
||||||
|
{
|
||||||
|
VerifyData *verify_data = user_data;
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
g_warning ("Match report: Finger not matched, retry error reported: %s",
|
||||||
|
error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print && fp_device_supports_capture (dev) &&
|
||||||
|
print_image_save (print, "verify.pgm"))
|
||||||
|
g_print ("Print image saved as verify.pgm\n");
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
char date_str[128];
|
||||||
|
|
||||||
|
verify_data->ret_value = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
g_date_strftime (date_str, G_N_ELEMENTS (date_str), "%Y-%m-%d\0",
|
||||||
|
fp_print_get_enroll_date (match));
|
||||||
|
g_debug ("Match report: device %s matched finger %s successifully "
|
||||||
|
"with print %s, enrolled on date %s by user %s",
|
||||||
|
fp_device_get_name (dev),
|
||||||
|
finger_to_string (fp_print_get_finger (match)),
|
||||||
|
fp_print_get_description (match), date_str,
|
||||||
|
fp_print_get_username (match));
|
||||||
|
|
||||||
|
g_print ("MATCH!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_debug ("Match report: Finger not matched");
|
||||||
|
g_print ("NO MATCH!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -143,7 +188,7 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
|||||||
{
|
{
|
||||||
g_warning ("Did you remember to enroll your %s finger first?",
|
g_warning ("Did you remember to enroll your %s finger first?",
|
||||||
finger_to_string (verify_data->finger));
|
finger_to_string (verify_data->finger));
|
||||||
g_main_loop_quit (verify_data->loop);
|
verify_quit (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,13 +197,14 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
|
|||||||
|
|
||||||
g_print ("Print loaded. Time to verify!\n");
|
g_print ("Print loaded. Time to verify!\n");
|
||||||
fp_device_verify (dev, verify_print, NULL,
|
fp_device_verify (dev, verify_print, NULL,
|
||||||
|
on_match_cb, verify_data, NULL,
|
||||||
(GAsyncReadyCallback) on_verify_completed,
|
(GAsyncReadyCallback) on_verify_completed,
|
||||||
verify_data);
|
verify_data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_warning ("Loading prints failed with error %s", error->message);
|
g_warning ("Loading prints failed with error %s", error->message);
|
||||||
g_main_loop_quit (verify_data->loop);
|
verify_quit (dev, verify_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +221,7 @@ start_verification (FpDevice *dev, VerifyData *verify_data)
|
|||||||
{
|
{
|
||||||
g_warning ("Unknown finger selected");
|
g_warning ("Unknown finger selected");
|
||||||
verify_data->ret_value = EXIT_FAILURE;
|
verify_data->ret_value = EXIT_FAILURE;
|
||||||
g_main_loop_quit (verify_data->loop);
|
verify_quit (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,12 +245,13 @@ start_verification (FpDevice *dev, VerifyData *verify_data)
|
|||||||
g_warning ("Failed to load fingerprint data");
|
g_warning ("Failed to load fingerprint data");
|
||||||
g_warning ("Did you remember to enroll your %s finger first?",
|
g_warning ("Did you remember to enroll your %s finger first?",
|
||||||
finger_to_string (verify_data->finger));
|
finger_to_string (verify_data->finger));
|
||||||
g_main_loop_quit (verify_data->loop);
|
verify_quit (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("Print loaded. Time to verify!\n");
|
g_print ("Print loaded. Time to verify!\n");
|
||||||
fp_device_verify (dev, verify_print, NULL,
|
fp_device_verify (dev, verify_print, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
(GAsyncReadyCallback) on_verify_completed,
|
(GAsyncReadyCallback) on_verify_completed,
|
||||||
verify_data);
|
verify_data);
|
||||||
}
|
}
|
||||||
@@ -220,7 +267,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
if (!fp_device_open_finish (dev, res, &error))
|
if (!fp_device_open_finish (dev, res, &error))
|
||||||
{
|
{
|
||||||
g_warning ("Failed to open device: %s", error->message);
|
g_warning ("Failed to open device: %s", error->message);
|
||||||
g_main_loop_quit (verify_data->loop);
|
verify_quit (dev, verify_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -585,8 +585,6 @@ capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
|
|||||||
|
|
||||||
G_DEBUG_HERE ();
|
G_DEBUG_HERE ();
|
||||||
|
|
||||||
/* XXX: cancellation was specially handled by doing nothing! */
|
|
||||||
|
|
||||||
/* either max frames captured or timed out waiting for the next frame */
|
/* either max frames captured or timed out waiting for the next frame */
|
||||||
if (!error ||
|
if (!error ||
|
||||||
(g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) &&
|
(g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) &&
|
||||||
|
|||||||
@@ -279,17 +279,10 @@ cmd_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error)
|
|||||||
self->cmd_ssm = NULL;
|
self->cmd_ssm = NULL;
|
||||||
|
|
||||||
/* Notify about the SSM failure from here instead. */
|
/* Notify about the SSM failure from here instead. */
|
||||||
if (error)
|
if (error || self->cmd_complete_on_removal)
|
||||||
{
|
|
||||||
callback (self, NULL, error);
|
callback (self, NULL, error);
|
||||||
}
|
|
||||||
else if (self->cmd_complete_on_removal)
|
|
||||||
{
|
|
||||||
callback (self, NULL, self->cmd_complete_error);
|
|
||||||
self->cmd_complete_error = NULL;
|
|
||||||
}
|
|
||||||
self->cmd_complete_on_removal = FALSE;
|
self->cmd_complete_on_removal = FALSE;
|
||||||
g_clear_pointer (&self->cmd_complete_error, g_error_free);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -527,8 +520,8 @@ list_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
|
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
|
||||||
{
|
{
|
||||||
g_autofree gchar *copy = g_strdup (userid);
|
g_autofree gchar *copy = g_strdup (userid);
|
||||||
|
g_autoptr(GDate) date = NULL;
|
||||||
gint32 date_ymd;
|
gint32 date_ymd;
|
||||||
GDate *date = NULL;
|
|
||||||
gint32 finger;
|
gint32 finger;
|
||||||
gchar *username;
|
gchar *username;
|
||||||
/* Try to parse information from the string. */
|
/* Try to parse information from the string. */
|
||||||
@@ -543,7 +536,6 @@ list_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
date = g_date_new ();
|
date = g_date_new ();
|
||||||
|
|
||||||
fp_print_set_enroll_date (print, date);
|
fp_print_set_enroll_date (print, date);
|
||||||
g_date_free (date);
|
|
||||||
|
|
||||||
copy[14] = '\0';
|
copy[14] = '\0';
|
||||||
finger = g_ascii_strtoll (copy + 13, NULL, 16);
|
finger = g_ascii_strtoll (copy + 13, NULL, 16);
|
||||||
@@ -582,6 +574,22 @@ list (FpDevice *device)
|
|||||||
synaptics_sensor_cmd (self, 0, BMKT_CMD_GET_TEMPLATE_RECORDS, NULL, 0, list_msg_cb);
|
synaptics_sensor_cmd (self, 0, BMKT_CMD_GET_TEMPLATE_RECORDS, NULL, 0, list_msg_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
verify_complete_after_finger_removal (FpiDeviceSynaptics *self)
|
||||||
|
{
|
||||||
|
FpDevice *device = FP_DEVICE (self);
|
||||||
|
|
||||||
|
if (self->finger_on_sensor)
|
||||||
|
{
|
||||||
|
fp_dbg ("delaying verify report until after finger removal!");
|
||||||
|
self->cmd_complete_on_removal = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_device_verify_complete (device, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
verify_msg_cb (FpiDeviceSynaptics *self,
|
verify_msg_cb (FpiDeviceSynaptics *self,
|
||||||
bmkt_response_t *resp,
|
bmkt_response_t *resp,
|
||||||
@@ -592,16 +600,13 @@ verify_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
fpi_device_verify_complete (device, FPI_MATCH_ERROR, NULL, error);
|
fpi_device_verify_complete (device, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp == NULL && self->cmd_complete_on_removal)
|
if (resp == NULL && self->cmd_complete_on_removal)
|
||||||
{
|
{
|
||||||
fpi_device_verify_complete (device,
|
fpi_device_verify_complete (device, NULL);
|
||||||
GPOINTER_TO_INT (self->cmd_complete_data),
|
|
||||||
NULL,
|
|
||||||
error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,39 +625,40 @@ verify_msg_cb (FpiDeviceSynaptics *self,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_VERIFY_FAIL:
|
case BMKT_RSP_VERIFY_FAIL:
|
||||||
if(resp->result == BMKT_SENSOR_STIMULUS_ERROR)
|
if (resp->result == BMKT_SENSOR_STIMULUS_ERROR)
|
||||||
{
|
{
|
||||||
fp_dbg ("delaying retry error until after finger removal!");
|
fp_info ("Match error occurred");
|
||||||
self->cmd_complete_on_removal = TRUE;
|
fpi_device_verify_report (device, FPI_MATCH_ERROR, NULL,
|
||||||
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_ERROR);
|
fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL));
|
||||||
self->cmd_complete_error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
|
verify_complete_after_finger_removal (self);
|
||||||
}
|
}
|
||||||
else if (resp->result == BMKT_FP_NO_MATCH)
|
else if (resp->result == BMKT_FP_NO_MATCH)
|
||||||
{
|
{
|
||||||
fp_dbg ("delaying match failure until after finger removal!");
|
fp_info ("Print didn't match");
|
||||||
self->cmd_complete_on_removal = TRUE;
|
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error);
|
||||||
self->cmd_complete_data = GINT_TO_POINTER (FPI_MATCH_FAIL);
|
verify_complete_after_finger_removal (self);
|
||||||
self->cmd_complete_error = NULL;
|
|
||||||
}
|
}
|
||||||
else if (BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
|
||||||
{
|
{
|
||||||
fp_info ("Print is not in database");
|
fp_info ("Print is not in database");
|
||||||
fpi_device_verify_complete (device,
|
fpi_device_verify_complete (device,
|
||||||
FPI_MATCH_ERROR,
|
|
||||||
NULL,
|
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_NOT_FOUND));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fp_warn ("Verify has failed: %d", resp->result);
|
fp_warn ("Verify has failed: %d", resp->result);
|
||||||
fpi_device_verify_complete (device, FPI_MATCH_FAIL, NULL, NULL);
|
fpi_device_verify_complete (device,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
|
"Unexpected result from device %d",
|
||||||
|
resp->result));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMKT_RSP_VERIFY_OK:
|
case BMKT_RSP_VERIFY_OK:
|
||||||
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
|
fp_info ("Verify was successful! for user: %s finger: %d score: %f",
|
||||||
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
verify_resp->user_id, verify_resp->finger_id, verify_resp->match_result);
|
||||||
fpi_device_verify_complete (device, FPI_MATCH_SUCCESS, NULL, NULL);
|
fpi_device_verify_report (device, FPI_MATCH_SUCCESS, NULL, NULL);
|
||||||
|
fpi_device_verify_complete (device, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -675,8 +681,6 @@ verify (FpDevice *device)
|
|||||||
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
|
if (!parse_print_data (data, &finger, &user_id, &user_id_len))
|
||||||
{
|
{
|
||||||
fpi_device_verify_complete (device,
|
fpi_device_verify_complete (device,
|
||||||
FPI_MATCH_ERROR,
|
|
||||||
NULL,
|
|
||||||
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,8 +110,6 @@ struct _FpiDeviceSynaptics
|
|||||||
FpiSsm *cmd_ssm;
|
FpiSsm *cmd_ssm;
|
||||||
FpiUsbTransfer *cmd_pending_transfer;
|
FpiUsbTransfer *cmd_pending_transfer;
|
||||||
gboolean cmd_complete_on_removal;
|
gboolean cmd_complete_on_removal;
|
||||||
GError *cmd_complete_error;
|
|
||||||
void *cmd_complete_data;
|
|
||||||
|
|
||||||
bmkt_sensor_version_t mis_version;
|
bmkt_sensor_version_t mis_version;
|
||||||
|
|
||||||
|
|||||||
@@ -902,8 +902,10 @@ enroll_start_sm_cb_msg28 (FpDevice *dev,
|
|||||||
FpiSsm *ssm = user_data;
|
FpiSsm *ssm = user_data;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
|
{
|
||||||
fpi_ssm_mark_failed (ssm, error);
|
fpi_ssm_mark_failed (ssm, error);
|
||||||
if (type != READ_MSG_RESPONSE)
|
}
|
||||||
|
else if (type != READ_MSG_RESPONSE)
|
||||||
{
|
{
|
||||||
fp_err ("expected response, got %d seq=%x", type, seq);
|
fp_err ("expected response, got %d seq=%x", type, seq);
|
||||||
fpi_ssm_mark_failed (ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
fpi_ssm_mark_failed (ssm, fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
|
||||||
@@ -1225,7 +1227,6 @@ enroll (FpDevice *dev)
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FpiMatchResult res;
|
|
||||||
GError *error;
|
GError *error;
|
||||||
} VerifyStopData;
|
} VerifyStopData;
|
||||||
|
|
||||||
@@ -1244,7 +1245,12 @@ verify_stop_deinit_cb (FpiSsm *ssm, FpDevice *dev, GError *error)
|
|||||||
if (error)
|
if (error)
|
||||||
fp_warn ("Error deinitializing: %s", error->message);
|
fp_warn ("Error deinitializing: %s", error->message);
|
||||||
|
|
||||||
fpi_device_verify_complete (dev, data->res, NULL, data->error);
|
if (data->error)
|
||||||
|
fpi_device_verify_complete (dev, data->error);
|
||||||
|
else
|
||||||
|
fpi_device_verify_complete (dev, g_steal_pointer (&error));
|
||||||
|
|
||||||
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1253,7 +1259,10 @@ do_verify_stop (FpDevice *dev, FpiMatchResult res, GError *error)
|
|||||||
VerifyStopData *data = g_new0 (VerifyStopData, 1);
|
VerifyStopData *data = g_new0 (VerifyStopData, 1);
|
||||||
FpiSsm *ssm = deinitsm_new (dev, data);
|
FpiSsm *ssm = deinitsm_new (dev, data);
|
||||||
|
|
||||||
data->res = res;
|
/* Report the error immediately if possible, otherwise delay it. */
|
||||||
|
if (!error && error->domain != FP_DEVICE_RETRY)
|
||||||
|
fpi_device_verify_report (dev, res, NULL, error);
|
||||||
|
else
|
||||||
data->error = error;
|
data->error = error;
|
||||||
|
|
||||||
fpi_ssm_start (ssm, verify_stop_deinit_cb);
|
fpi_ssm_start (ssm, verify_stop_deinit_cb);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "fpi-compat.h"
|
||||||
#include "fpi-assembling.h"
|
#include "fpi-assembling.h"
|
||||||
#include "fpi-device.h"
|
#include "fpi-device.h"
|
||||||
#include "fpi-image-device.h"
|
#include "fpi-image-device.h"
|
||||||
|
|||||||
@@ -136,8 +136,7 @@ usb_device_added_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx)
|
|||||||
for (i = 0; i < priv->drivers->len; i++)
|
for (i = 0; i < priv->drivers->len; i++)
|
||||||
{
|
{
|
||||||
GType driver = g_array_index (priv->drivers, GType, i);
|
GType driver = g_array_index (priv->drivers, GType, i);
|
||||||
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
|
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
|
|
||||||
const FpIdEntry *entry;
|
const FpIdEntry *entry;
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
@@ -288,8 +287,7 @@ fp_context_init (FpContext *self)
|
|||||||
for (i = 0; i < priv->drivers->len;)
|
for (i = 0; i < priv->drivers->len;)
|
||||||
{
|
{
|
||||||
GType driver = g_array_index (priv->drivers, GType, i);
|
GType driver = g_array_index (priv->drivers, GType, i);
|
||||||
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
|
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
|
|
||||||
|
|
||||||
if (!is_driver_allowed (cls->id))
|
if (!is_driver_allowed (cls->id))
|
||||||
g_array_remove_index (priv->drivers, i);
|
g_array_remove_index (priv->drivers, i);
|
||||||
@@ -363,8 +361,7 @@ fp_context_enumerate (FpContext *context)
|
|||||||
for (i = 0; i < priv->drivers->len; i++)
|
for (i = 0; i < priv->drivers->len; i++)
|
||||||
{
|
{
|
||||||
GType driver = g_array_index (priv->drivers, GType, i);
|
GType driver = g_array_index (priv->drivers, GType, i);
|
||||||
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
|
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
|
|
||||||
const FpIdEntry *entry;
|
const FpIdEntry *entry;
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_VIRTUAL)
|
if (cls->type != FP_DEVICE_TYPE_VIRTUAL)
|
||||||
|
|||||||
@@ -63,3 +63,20 @@ typedef struct
|
|||||||
} FpEnrollData;
|
} FpEnrollData;
|
||||||
|
|
||||||
void enroll_data_free (FpEnrollData *enroll_data);
|
void enroll_data_free (FpEnrollData *enroll_data);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FpPrint *enrolled_print; /* verify */
|
||||||
|
GPtrArray *gallery; /* identify */
|
||||||
|
|
||||||
|
gboolean result_reported;
|
||||||
|
FpPrint *match;
|
||||||
|
FpPrint *print;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
|
FpMatchCb match_cb;
|
||||||
|
gpointer match_data;
|
||||||
|
GDestroyNotify match_destroy;
|
||||||
|
} FpMatchData;
|
||||||
|
|
||||||
|
void match_data_free (FpMatchData *match_data);
|
||||||
|
|||||||
+61
-10
@@ -775,6 +775,7 @@ fp_device_enroll (FpDevice *device,
|
|||||||
data->print = g_object_ref_sink (template_print);
|
data->print = g_object_ref_sink (template_print);
|
||||||
data->enroll_progress_cb = progress_cb;
|
data->enroll_progress_cb = progress_cb;
|
||||||
data->enroll_progress_data = progress_data;
|
data->enroll_progress_data = progress_data;
|
||||||
|
data->enroll_progress_destroy = progress_destroy;
|
||||||
|
|
||||||
// Attach the progress data as task data so that it is destroyed
|
// Attach the progress data as task data so that it is destroyed
|
||||||
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) enroll_data_free);
|
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) enroll_data_free);
|
||||||
@@ -808,10 +809,13 @@ fp_device_enroll_finish (FpDevice *device,
|
|||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @enrolled_print: a #FpPrint to verify
|
* @enrolled_print: a #FpPrint to verify
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
|
* @match_cb: (nullable) (scope notified): match reporting callback
|
||||||
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
|
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
||||||
* @callback: the function to call on completion
|
* @callback: the function to call on completion
|
||||||
* @user_data: the data to pass to @callback
|
* @user_data: the data to pass to @callback
|
||||||
*
|
*
|
||||||
* Start an asynchronous operation to close the device. The callback will
|
* Start an asynchronous operation to verify a print. The callback will
|
||||||
* be called once the operation has finished. Retrieve the result with
|
* be called once the operation has finished. Retrieve the result with
|
||||||
* fp_device_verify_finish().
|
* fp_device_verify_finish().
|
||||||
*/
|
*/
|
||||||
@@ -819,11 +823,15 @@ void
|
|||||||
fp_device_verify (FpDevice *device,
|
fp_device_verify (FpDevice *device,
|
||||||
FpPrint *enrolled_print,
|
FpPrint *enrolled_print,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
|
GDestroyNotify match_destroy,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data;
|
||||||
|
|
||||||
task = g_task_new (device, cancellable, callback, user_data);
|
task = g_task_new (device, cancellable, callback, user_data);
|
||||||
if (g_task_return_error_if_cancelled (task))
|
if (g_task_return_error_if_cancelled (task))
|
||||||
@@ -847,9 +855,14 @@ fp_device_verify (FpDevice *device,
|
|||||||
priv->current_task = g_steal_pointer (&task);
|
priv->current_task = g_steal_pointer (&task);
|
||||||
maybe_cancel_on_cancelled (device, cancellable);
|
maybe_cancel_on_cancelled (device, cancellable);
|
||||||
|
|
||||||
g_task_set_task_data (priv->current_task,
|
data = g_new0 (FpMatchData, 1);
|
||||||
g_object_ref (enrolled_print),
|
data->enrolled_print = g_object_ref (enrolled_print);
|
||||||
g_object_unref);
|
data->match_cb = match_cb;
|
||||||
|
data->match_data = match_data;
|
||||||
|
data->match_destroy = match_destroy;
|
||||||
|
|
||||||
|
// Attach the match data as task data so that it is destroyed
|
||||||
|
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) match_data_free);
|
||||||
|
|
||||||
FP_DEVICE_GET_CLASS (device)->verify (device);
|
FP_DEVICE_GET_CLASS (device)->verify (device);
|
||||||
}
|
}
|
||||||
@@ -885,7 +898,11 @@ fp_device_verify_finish (FpDevice *device,
|
|||||||
|
|
||||||
if (print)
|
if (print)
|
||||||
{
|
{
|
||||||
*print = g_object_get_data (G_OBJECT (result), "print");
|
FpMatchData *data;
|
||||||
|
|
||||||
|
data = g_task_get_task_data (G_TASK (result));
|
||||||
|
|
||||||
|
*print = data->print;
|
||||||
if (*print)
|
if (*print)
|
||||||
g_object_ref (*print);
|
g_object_ref (*print);
|
||||||
}
|
}
|
||||||
@@ -901,6 +918,9 @@ fp_device_verify_finish (FpDevice *device,
|
|||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
|
* @match_cb: (nullable) (scope notified): match reporting callback
|
||||||
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
|
* @match_destroy: (destroy match_data): Destroy notify for @match_data
|
||||||
* @callback: the function to call on completion
|
* @callback: the function to call on completion
|
||||||
* @user_data: the data to pass to @callback
|
* @user_data: the data to pass to @callback
|
||||||
*
|
*
|
||||||
@@ -912,11 +932,15 @@ void
|
|||||||
fp_device_identify (FpDevice *device,
|
fp_device_identify (FpDevice *device,
|
||||||
GPtrArray *prints,
|
GPtrArray *prints,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
|
GDestroyNotify match_destroy,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data;
|
||||||
|
|
||||||
task = g_task_new (device, cancellable, callback, user_data);
|
task = g_task_new (device, cancellable, callback, user_data);
|
||||||
if (g_task_return_error_if_cancelled (task))
|
if (g_task_return_error_if_cancelled (task))
|
||||||
@@ -940,9 +964,14 @@ fp_device_identify (FpDevice *device,
|
|||||||
priv->current_task = g_steal_pointer (&task);
|
priv->current_task = g_steal_pointer (&task);
|
||||||
maybe_cancel_on_cancelled (device, cancellable);
|
maybe_cancel_on_cancelled (device, cancellable);
|
||||||
|
|
||||||
g_task_set_task_data (priv->current_task,
|
data = g_new0 (FpMatchData, 1);
|
||||||
g_ptr_array_ref (prints),
|
data->gallery = g_ptr_array_ref (prints);
|
||||||
(GDestroyNotify) g_ptr_array_unref);
|
data->match_cb = match_cb;
|
||||||
|
data->match_data = match_data;
|
||||||
|
data->match_destroy = match_destroy;
|
||||||
|
|
||||||
|
// Attach the match data as task data so that it is destroyed
|
||||||
|
g_task_set_task_data (priv->current_task, data, (GDestroyNotify) match_data_free);
|
||||||
|
|
||||||
FP_DEVICE_GET_CLASS (device)->identify (device);
|
FP_DEVICE_GET_CLASS (device)->identify (device);
|
||||||
}
|
}
|
||||||
@@ -973,15 +1002,19 @@ fp_device_identify_finish (FpDevice *device,
|
|||||||
FpPrint **print,
|
FpPrint **print,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
FpMatchData *data;
|
||||||
|
|
||||||
|
data = g_task_get_task_data (G_TASK (result));
|
||||||
|
|
||||||
if (print)
|
if (print)
|
||||||
{
|
{
|
||||||
*print = g_object_get_data (G_OBJECT (result), "print");
|
*print = data->print;
|
||||||
if (*print)
|
if (*print)
|
||||||
g_object_ref (*print);
|
g_object_ref (*print);
|
||||||
}
|
}
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
*match = g_object_get_data (G_OBJECT (result), "match");
|
*match = data->match;
|
||||||
if (*match)
|
if (*match)
|
||||||
g_object_ref (*match);
|
g_object_ref (*match);
|
||||||
}
|
}
|
||||||
@@ -1180,6 +1213,14 @@ fp_device_list_prints (FpDevice *device,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fp_device_has_storage (device))
|
||||||
|
{
|
||||||
|
g_task_return_error (task,
|
||||||
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
"Device has no storage"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
priv->current_action = FPI_DEVICE_ACTION_LIST;
|
priv->current_action = FPI_DEVICE_ACTION_LIST;
|
||||||
priv->current_task = g_steal_pointer (&task);
|
priv->current_task = g_steal_pointer (&task);
|
||||||
maybe_cancel_on_cancelled (device, cancellable);
|
maybe_cancel_on_cancelled (device, cancellable);
|
||||||
@@ -1308,6 +1349,8 @@ fp_device_enroll_sync (FpDevice *device,
|
|||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @enrolled_print: a #FpPrint to verify
|
* @enrolled_print: a #FpPrint to verify
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
|
* @match_cb: (nullable) (scope call): match reporting callback
|
||||||
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
* @match: (out): Whether the user presented the correct finger
|
* @match: (out): Whether the user presented the correct finger
|
||||||
* @print: (out) (transfer full) (nullable): Location to store the scanned print, or %NULL to ignore
|
* @print: (out) (transfer full) (nullable): Location to store the scanned print, or %NULL to ignore
|
||||||
* @error: Return location for errors, or %NULL to ignore
|
* @error: Return location for errors, or %NULL to ignore
|
||||||
@@ -1320,6 +1363,8 @@ gboolean
|
|||||||
fp_device_verify_sync (FpDevice *device,
|
fp_device_verify_sync (FpDevice *device,
|
||||||
FpPrint *enrolled_print,
|
FpPrint *enrolled_print,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
gboolean *match,
|
gboolean *match,
|
||||||
FpPrint **print,
|
FpPrint **print,
|
||||||
GError **error)
|
GError **error)
|
||||||
@@ -1331,6 +1376,7 @@ fp_device_verify_sync (FpDevice *device,
|
|||||||
fp_device_verify (device,
|
fp_device_verify (device,
|
||||||
enrolled_print,
|
enrolled_print,
|
||||||
cancellable,
|
cancellable,
|
||||||
|
match_cb, match_data, NULL,
|
||||||
async_result_ready, &task);
|
async_result_ready, &task);
|
||||||
while (!task)
|
while (!task)
|
||||||
g_main_context_iteration (NULL, TRUE);
|
g_main_context_iteration (NULL, TRUE);
|
||||||
@@ -1343,6 +1389,8 @@ fp_device_verify_sync (FpDevice *device,
|
|||||||
* @device: a #FpDevice
|
* @device: a #FpDevice
|
||||||
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
* @prints: (element-type FpPrint) (transfer none): #GPtrArray of #FpPrint
|
||||||
* @cancellable: (nullable): a #GCancellable, or %NULL
|
* @cancellable: (nullable): a #GCancellable, or %NULL
|
||||||
|
* @match_cb: (nullable) (scope call): match reporting callback
|
||||||
|
* @match_data: (closure match_cb): user data for @match_cb
|
||||||
* @match: (out) (transfer full) (nullable): Location for the matched #FpPrint, or %NULL
|
* @match: (out) (transfer full) (nullable): Location for the matched #FpPrint, or %NULL
|
||||||
* @print: (out) (transfer full) (nullable): Location for the new #FpPrint, or %NULL
|
* @print: (out) (transfer full) (nullable): Location for the new #FpPrint, or %NULL
|
||||||
* @error: Return location for errors, or %NULL to ignore
|
* @error: Return location for errors, or %NULL to ignore
|
||||||
@@ -1355,6 +1403,8 @@ gboolean
|
|||||||
fp_device_identify_sync (FpDevice *device,
|
fp_device_identify_sync (FpDevice *device,
|
||||||
GPtrArray *prints,
|
GPtrArray *prints,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
FpPrint **match,
|
FpPrint **match,
|
||||||
FpPrint **print,
|
FpPrint **print,
|
||||||
GError **error)
|
GError **error)
|
||||||
@@ -1366,6 +1416,7 @@ fp_device_identify_sync (FpDevice *device,
|
|||||||
fp_device_identify (device,
|
fp_device_identify (device,
|
||||||
prints,
|
prints,
|
||||||
cancellable,
|
cancellable,
|
||||||
|
match_cb, match_data, NULL,
|
||||||
async_result_ready, &task);
|
async_result_ready, &task);
|
||||||
while (!task)
|
while (!task)
|
||||||
g_main_context_iteration (NULL, TRUE);
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
|||||||
@@ -125,6 +125,43 @@ typedef void (*FpEnrollProgress) (FpDevice *device,
|
|||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError *error);
|
GError *error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FpMatchCb:
|
||||||
|
* @device: a #FpDevice
|
||||||
|
* @match: (nullable) (transfer none): The matching print if any matched @print
|
||||||
|
* @print: (nullable) (transfer none): The newly scanned print
|
||||||
|
* @user_data: (nullable) (transfer none): User provided data
|
||||||
|
* @error: (nullable) (transfer none): #GError or %NULL
|
||||||
|
*
|
||||||
|
* Report the result of a match (identify or verify) operation.
|
||||||
|
*
|
||||||
|
* If @match is non-%NULL, then it is set to the matching #FpPrint as passed
|
||||||
|
* to the match operation. In this case @error will always be %NULL.
|
||||||
|
*
|
||||||
|
* If @error is not %NULL then its domain is guaranteed to be
|
||||||
|
* %FP_DEVICE_RETRY. All other error conditions will not be reported using
|
||||||
|
* this callback. If such an error occurs before a match/no-match decision
|
||||||
|
* can be made, then this callback will not be called. Should an error
|
||||||
|
* happen afterwards, then you will get a match report through this callback
|
||||||
|
* and an error when the operation finishes.
|
||||||
|
*
|
||||||
|
* If @match and @error are %NULL, then a finger was presented but it did not
|
||||||
|
* match any known print.
|
||||||
|
*
|
||||||
|
* @print represents the newly scanned print. The driver may or may not
|
||||||
|
* provide this information. Image based devices will provide it and it
|
||||||
|
* allows access to the raw data.
|
||||||
|
*
|
||||||
|
* This callback exists because it makes sense for drivers to wait e.g. on
|
||||||
|
* finger removal before completing the match operation. However, the
|
||||||
|
* success/failure can often be reported at an earlier time, and there is
|
||||||
|
* no need to make the user wait.
|
||||||
|
*/
|
||||||
|
typedef void (*FpMatchCb) (FpDevice *device,
|
||||||
|
FpPrint *match,
|
||||||
|
FpPrint *print,
|
||||||
|
gpointer user_data,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
const gchar *fp_device_get_driver (FpDevice *device);
|
const gchar *fp_device_get_driver (FpDevice *device);
|
||||||
const gchar *fp_device_get_device_id (FpDevice *device);
|
const gchar *fp_device_get_device_id (FpDevice *device);
|
||||||
@@ -160,12 +197,18 @@ void fp_device_enroll (FpDevice *device,
|
|||||||
void fp_device_verify (FpDevice *device,
|
void fp_device_verify (FpDevice *device,
|
||||||
FpPrint *enrolled_print,
|
FpPrint *enrolled_print,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
|
GDestroyNotify match_destroy,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
void fp_device_identify (FpDevice *device,
|
void fp_device_identify (FpDevice *device,
|
||||||
GPtrArray *prints,
|
GPtrArray *prints,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
|
GDestroyNotify match_destroy,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
@@ -231,12 +274,16 @@ FpPrint * fp_device_enroll_sync (FpDevice *device,
|
|||||||
gboolean fp_device_verify_sync (FpDevice *device,
|
gboolean fp_device_verify_sync (FpDevice *device,
|
||||||
FpPrint *enrolled_print,
|
FpPrint *enrolled_print,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
gboolean *match,
|
gboolean *match,
|
||||||
FpPrint **print,
|
FpPrint **print,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean fp_device_identify_sync (FpDevice *device,
|
gboolean fp_device_identify_sync (FpDevice *device,
|
||||||
GPtrArray *prints,
|
GPtrArray *prints,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
FpMatchCb match_cb,
|
||||||
|
gpointer match_data,
|
||||||
FpPrint **match,
|
FpPrint **match,
|
||||||
FpPrint **print,
|
FpPrint **print,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define FP_COMPONENT "print"
|
#define FP_COMPONENT "print"
|
||||||
|
|
||||||
#include "fp-print-private.h"
|
#include "fp-print-private.h"
|
||||||
|
#include "fpi-compat.h"
|
||||||
#include "fpi-log.h"
|
#include "fpi-log.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -752,8 +753,8 @@ fp_print_deserialize (const guchar *data,
|
|||||||
g_autoptr(GVariant) raw_value = NULL;
|
g_autoptr(GVariant) raw_value = NULL;
|
||||||
g_autoptr(GVariant) value = NULL;
|
g_autoptr(GVariant) value = NULL;
|
||||||
g_autoptr(GVariant) print_data = NULL;
|
g_autoptr(GVariant) print_data = NULL;
|
||||||
|
g_autoptr(GDate) date = NULL;
|
||||||
guchar *aligned_data = NULL;
|
guchar *aligned_data = NULL;
|
||||||
GDate *date = NULL;
|
|
||||||
guint8 finger_int8;
|
guint8 finger_int8;
|
||||||
FpFinger finger;
|
FpFinger finger;
|
||||||
g_autofree gchar *username = NULL;
|
g_autofree gchar *username = NULL;
|
||||||
@@ -881,8 +882,6 @@ fp_print_deserialize (const guchar *data,
|
|||||||
"enroll_date", date,
|
"enroll_date", date,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
g_date_free (date);
|
|
||||||
|
|
||||||
return g_steal_pointer (&result);
|
return g_steal_pointer (&result);
|
||||||
|
|
||||||
invalid_format:
|
invalid_format:
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Benjamin Berg <bberg@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION (2, 57, 0)
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GTypeClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GEnumClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GParamSpec, g_param_spec_unref);
|
||||||
|
#else
|
||||||
|
/* Re-define G_SOURCE_FUNC as we are technically not allowed to use it with
|
||||||
|
* the version we depend on currently. */
|
||||||
|
#undef G_SOURCE_FUNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void))(f))
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION (2, 63, 3)
|
||||||
|
typedef struct _FpDeviceClass FpDeviceClass;
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpDeviceClass, g_type_class_unref);
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GDate, g_date_free);
|
||||||
|
#endif
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <gusb.h>
|
#include <gusb.h>
|
||||||
#include "fp-context.h"
|
#include "fp-context.h"
|
||||||
|
#include "fpi-compat.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_get_driver_types:
|
* fpi_get_driver_types:
|
||||||
|
|||||||
+242
-48
@@ -420,6 +420,23 @@ enroll_data_free (FpEnrollData *data)
|
|||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
match_data_free (FpMatchData *data)
|
||||||
|
{
|
||||||
|
g_clear_object (&data->print);
|
||||||
|
g_clear_object (&data->match);
|
||||||
|
g_clear_error (&data->error);
|
||||||
|
|
||||||
|
if (data->match_destroy)
|
||||||
|
data->match_destroy (data->match_data);
|
||||||
|
data->match_data = NULL;
|
||||||
|
|
||||||
|
g_clear_object (&data->enrolled_print);
|
||||||
|
g_clear_pointer (&data->gallery, g_ptr_array_unref);
|
||||||
|
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_get_enroll_data:
|
* fpi_device_get_enroll_data:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
@@ -476,12 +493,16 @@ fpi_device_get_verify_data (FpDevice *device,
|
|||||||
FpPrint **print)
|
FpPrint **print)
|
||||||
{
|
{
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data;
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_DEVICE (device));
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
|
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
|
||||||
|
|
||||||
|
data = g_task_get_task_data (priv->current_task);
|
||||||
|
g_assert (data);
|
||||||
|
|
||||||
if (print)
|
if (print)
|
||||||
*print = g_task_get_task_data (priv->current_task);
|
*print = data->enrolled_print;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -496,12 +517,16 @@ fpi_device_get_identify_data (FpDevice *device,
|
|||||||
GPtrArray **prints)
|
GPtrArray **prints)
|
||||||
{
|
{
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data;
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_DEVICE (device));
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
|
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
|
||||||
|
|
||||||
|
data = g_task_get_task_data (priv->current_task);
|
||||||
|
g_assert (data);
|
||||||
|
|
||||||
if (prints)
|
if (prints)
|
||||||
*prints = g_task_get_task_data (priv->current_task);
|
*prints = data->gallery;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -596,11 +621,11 @@ fpi_device_action_error (FpDevice *device,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FPI_DEVICE_ACTION_VERIFY:
|
case FPI_DEVICE_ACTION_VERIFY:
|
||||||
fpi_device_verify_complete (device, FPI_MATCH_ERROR, NULL, error);
|
fpi_device_verify_complete (device, error);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPI_DEVICE_ACTION_IDENTIFY:
|
case FPI_DEVICE_ACTION_IDENTIFY:
|
||||||
fpi_device_identify_complete (device, NULL, NULL, error);
|
fpi_device_identify_complete (device, error);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPI_DEVICE_ACTION_CAPTURE:
|
case FPI_DEVICE_ACTION_CAPTURE:
|
||||||
@@ -826,8 +851,6 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
|||||||
g_debug ("Device reported close completion");
|
g_debug ("Device reported close completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
priv->is_open = FALSE;
|
|
||||||
g_object_notify (G_OBJECT (device), "open");
|
|
||||||
|
|
||||||
switch (priv->type)
|
switch (priv->type)
|
||||||
{
|
{
|
||||||
@@ -852,10 +875,16 @@ fpi_device_close_complete (FpDevice *device, GError *error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
|
{
|
||||||
|
priv->is_open = FALSE;
|
||||||
|
g_object_notify (G_OBJECT (device), "open");
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
||||||
GUINT_TO_POINTER (TRUE));
|
GUINT_TO_POINTER (TRUE));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -907,64 +936,68 @@ fpi_device_enroll_complete (FpDevice *device, FpPrint *print, GError *error)
|
|||||||
/**
|
/**
|
||||||
* fpi_device_verify_complete:
|
* fpi_device_verify_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @result: The #FpiMatchResult of the operation
|
|
||||||
* @print: The scanned #FpPrint
|
|
||||||
* @error: A #GError if result is %FPI_MATCH_ERROR
|
* @error: A #GError if result is %FPI_MATCH_ERROR
|
||||||
*
|
*
|
||||||
* Finish an ongoing verify operation. The returned print should be
|
* Finish an ongoing verify operation. The returned print should be
|
||||||
* representing the new scan and not the one passed for verification.
|
* representing the new scan and not the one passed for verification.
|
||||||
|
*
|
||||||
|
* Note that @error should only be set for actual errors. In the case
|
||||||
|
* of retry errors, report these using fpi_device_verify_report()
|
||||||
|
* and then call this function without any error argument.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_device_verify_complete (FpDevice *device,
|
fpi_device_verify_complete (FpDevice *device,
|
||||||
FpiMatchResult result,
|
|
||||||
FpPrint *print,
|
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data;
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_DEVICE (device));
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
|
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
|
||||||
|
|
||||||
g_debug ("Device reported verify completion");
|
g_debug ("Device reported verify completion");
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
data = g_task_get_task_data (priv->current_task);
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (priv->current_task),
|
clear_device_cancel_action (device);
|
||||||
"print",
|
|
||||||
print,
|
|
||||||
g_object_unref);
|
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
if (result != FPI_MATCH_ERROR)
|
if (!data->result_reported)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported successful verify complete but did not report the result earlier. Reporting error instead");
|
||||||
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
|
}
|
||||||
|
else if (data->error)
|
||||||
|
{
|
||||||
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, g_steal_pointer (&data->error));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_INT,
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_INT,
|
||||||
GINT_TO_POINTER (result));
|
GINT_TO_POINTER (data->match != NULL ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_warning ("Driver did not provide an error for a failed verify operation!");
|
|
||||||
error = fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
|
|
||||||
"Driver failed to provide an error!");
|
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
/* Replace a retry error with a general error, this is a driver bug. */
|
||||||
if (result != FPI_MATCH_ERROR)
|
if (error->domain == FP_DEVICE_RETRY)
|
||||||
{
|
{
|
||||||
g_warning ("Driver passed an error but also provided a match result, returning error!");
|
g_warning ("Driver reported a retry error to fpi_device_verify_complete. "
|
||||||
g_object_unref (print);
|
"This is not permissible and needs to be reported using "
|
||||||
|
"fpi_device_verify_report, reporting general verification "
|
||||||
|
"failure instead.");
|
||||||
|
g_clear_error (&error);
|
||||||
|
error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
|
||||||
}
|
}
|
||||||
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_device_identify_complete:
|
* fpi_device_identify_complete:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @match: The matching #FpPrint from the passed gallery, or %NULL if none matched
|
|
||||||
* @print: The scanned #FpPrint, may be %NULL
|
|
||||||
* @error: The #GError or %NULL on success
|
* @error: The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Finish an ongoing identify operation. The match that was identified is
|
* Finish an ongoing identify operation. The match that was identified is
|
||||||
@@ -973,41 +1006,51 @@ fpi_device_verify_complete (FpDevice *device,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_device_identify_complete (FpDevice *device,
|
fpi_device_identify_complete (FpDevice *device,
|
||||||
FpPrint *match,
|
|
||||||
FpPrint *print,
|
|
||||||
GError *error)
|
GError *error)
|
||||||
{
|
{
|
||||||
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data;
|
||||||
|
|
||||||
g_return_if_fail (FP_IS_DEVICE (device));
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
|
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
|
||||||
|
|
||||||
g_debug ("Device reported identify completion");
|
g_debug ("Device reported identify completion");
|
||||||
|
|
||||||
|
data = g_task_get_task_data (priv->current_task);
|
||||||
|
|
||||||
clear_device_cancel_action (device);
|
clear_device_cancel_action (device);
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (priv->current_task),
|
|
||||||
"print",
|
|
||||||
print,
|
|
||||||
g_object_unref);
|
|
||||||
g_object_set_data_full (G_OBJECT (priv->current_task),
|
|
||||||
"match",
|
|
||||||
match,
|
|
||||||
g_object_unref);
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
|
if (!data->result_reported)
|
||||||
GUINT_TO_POINTER (TRUE));
|
{
|
||||||
|
g_warning ("Driver reported successful identify complete but did not report the result earlier. Reporting error instead");
|
||||||
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_GENERAL));
|
||||||
|
}
|
||||||
|
else if (data->error)
|
||||||
|
{
|
||||||
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, g_steal_pointer (&data->error));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_INT, GINT_TO_POINTER (TRUE));
|
||||||
if (match)
|
|
||||||
{
|
|
||||||
g_warning ("Driver passed an error but also provided a match result, returning error!");
|
|
||||||
g_clear_object (&match);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Replace a retry error with a general error, this is a driver bug. */
|
||||||
|
if (error->domain == FP_DEVICE_RETRY)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported a retry error to fpi_device_identify_complete. "
|
||||||
|
"This is not permissible and needs to be reported using "
|
||||||
|
"fpi_device_identify_report, reporting general identification "
|
||||||
|
"failure instead.");
|
||||||
|
g_clear_error (&error);
|
||||||
|
error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
|
||||||
|
}
|
||||||
|
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1134,7 +1177,7 @@ fpi_device_list_complete (FpDevice *device,
|
|||||||
* fpi_device_enroll_progress:
|
* fpi_device_enroll_progress:
|
||||||
* @device: The #FpDevice
|
* @device: The #FpDevice
|
||||||
* @completed_stages: The number of stages that are completed at this point
|
* @completed_stages: The number of stages that are completed at this point
|
||||||
* @print: (transfer full): The #FpPrint for the newly completed stage or %NULL on failure
|
* @print: (transfer floating): The #FpPrint for the newly completed stage or %NULL on failure
|
||||||
* @error: (transfer full): The #GError or %NULL on success
|
* @error: (transfer full): The #GError or %NULL on success
|
||||||
*
|
*
|
||||||
* Notify about the progress of the enroll operation. This is important for UI interaction.
|
* Notify about the progress of the enroll operation. This is important for UI interaction.
|
||||||
@@ -1155,6 +1198,9 @@ fpi_device_enroll_progress (FpDevice *device,
|
|||||||
|
|
||||||
g_debug ("Device reported enroll progress, reported %i of %i have been completed", completed_stages, priv->nr_enroll_stages);
|
g_debug ("Device reported enroll progress, reported %i of %i have been completed", completed_stages, priv->nr_enroll_stages);
|
||||||
|
|
||||||
|
if (print)
|
||||||
|
g_object_ref_sink (print);
|
||||||
|
|
||||||
if (error && print)
|
if (error && print)
|
||||||
{
|
{
|
||||||
g_warning ("Driver passed an error and also provided a print, returning error!");
|
g_warning ("Driver passed an error and also provided a print, returning error!");
|
||||||
@@ -1175,3 +1221,151 @@ fpi_device_enroll_progress (FpDevice *device,
|
|||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
g_clear_object (&print);
|
g_clear_object (&print);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_verify_report:
|
||||||
|
* @device: The #FpDevice
|
||||||
|
* @result: The #FpiMatchResult of the operation
|
||||||
|
* @print: (transfer floating) The scanned #FpPrint
|
||||||
|
* @error: A #GError if result is %FPI_MATCH_ERROR
|
||||||
|
*
|
||||||
|
* Report the result of a verify operation. Note that the passed @error must be
|
||||||
|
* a retry error with the %FP_DEVICE_RETRY domain. For all other error cases,
|
||||||
|
* the error should passed to fpi_device_verify_complete().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_device_verify_report (FpDevice *device,
|
||||||
|
FpiMatchResult result,
|
||||||
|
FpPrint *print,
|
||||||
|
GError *error)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data = g_task_get_task_data (priv->current_task);
|
||||||
|
gboolean call_cb = TRUE;
|
||||||
|
|
||||||
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
|
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_VERIFY);
|
||||||
|
g_return_if_fail (data->result_reported == FALSE);
|
||||||
|
|
||||||
|
data->result_reported = TRUE;
|
||||||
|
|
||||||
|
g_debug ("Device reported verify result");
|
||||||
|
|
||||||
|
if (print)
|
||||||
|
print = g_object_ref_sink (print);
|
||||||
|
|
||||||
|
if (error || result == FPI_MATCH_ERROR)
|
||||||
|
{
|
||||||
|
if (result != FPI_MATCH_ERROR)
|
||||||
|
g_warning ("Driver reported an error code without setting match result to error!");
|
||||||
|
|
||||||
|
if (error == NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported an error without specifying a retry code, assuming general retry error!");
|
||||||
|
error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported a print together with an error!");
|
||||||
|
g_clear_object (&print);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->error = error;
|
||||||
|
|
||||||
|
if (error->domain != FP_DEVICE_RETRY)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported a verify error that was not in the retry domain, delaying report!");
|
||||||
|
call_cb = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (result == FPI_MATCH_SUCCESS)
|
||||||
|
{
|
||||||
|
fpi_device_get_verify_data (device, &data->match);
|
||||||
|
g_object_ref (data->match);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->print = g_steal_pointer (&print);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (call_cb && data->match_cb)
|
||||||
|
data->match_cb (device, data->match, data->print, data->match_data, data->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_identify_report:
|
||||||
|
* @device: The #FpDevice
|
||||||
|
* @match: (transfer none): The #FpPrint from the gallery that matched
|
||||||
|
* @print: (transfer floating): The scanned #FpPrint
|
||||||
|
* @error: A #GError if result is %FPI_MATCH_ERROR
|
||||||
|
*
|
||||||
|
* Report the result of a identify operation. Note that the passed @error must be
|
||||||
|
* a retry error with the %FP_DEVICE_RETRY domain. For all other error cases,
|
||||||
|
* the error should passed to fpi_device_identify_complete().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_device_identify_report (FpDevice *device,
|
||||||
|
FpPrint *match,
|
||||||
|
FpPrint *print,
|
||||||
|
GError *error)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
FpMatchData *data = g_task_get_task_data (priv->current_task);
|
||||||
|
gboolean call_cb = TRUE;
|
||||||
|
|
||||||
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
|
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_IDENTIFY);
|
||||||
|
g_return_if_fail (data->result_reported == FALSE);
|
||||||
|
|
||||||
|
data->result_reported = TRUE;
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
g_object_ref (match);
|
||||||
|
|
||||||
|
if (print)
|
||||||
|
print = g_object_ref_sink (print);
|
||||||
|
|
||||||
|
if (match && !g_ptr_array_find (data->gallery, match, NULL))
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported a match to a print that was not in the gallery, ignoring match.");
|
||||||
|
g_clear_object (&match);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("Device reported identify result");
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
if (match != NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported an error code but also provided a match!");
|
||||||
|
g_clear_object (&match);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported a print together with an error!");
|
||||||
|
g_clear_object (&print);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->error = error;
|
||||||
|
|
||||||
|
if (error->domain != FP_DEVICE_RETRY)
|
||||||
|
{
|
||||||
|
g_warning ("Driver reported a verify error that was not in the retry domain, delaying report!");
|
||||||
|
call_cb = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (match)
|
||||||
|
data->match = g_steal_pointer (&match);
|
||||||
|
|
||||||
|
if (print)
|
||||||
|
data->print = g_steal_pointer (&print);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (call_cb && data->match_cb)
|
||||||
|
data->match_cb (device, data->match, data->print, data->match_data, data->error);
|
||||||
|
}
|
||||||
|
|||||||
@@ -238,12 +238,8 @@ void fpi_device_enroll_complete (FpDevice *device,
|
|||||||
FpPrint *print,
|
FpPrint *print,
|
||||||
GError *error);
|
GError *error);
|
||||||
void fpi_device_verify_complete (FpDevice *device,
|
void fpi_device_verify_complete (FpDevice *device,
|
||||||
FpiMatchResult result,
|
|
||||||
FpPrint *print,
|
|
||||||
GError *error);
|
GError *error);
|
||||||
void fpi_device_identify_complete (FpDevice *device,
|
void fpi_device_identify_complete (FpDevice *device,
|
||||||
FpPrint *match,
|
|
||||||
FpPrint *print,
|
|
||||||
GError *error);
|
GError *error);
|
||||||
void fpi_device_capture_complete (FpDevice *device,
|
void fpi_device_capture_complete (FpDevice *device,
|
||||||
FpImage *image,
|
FpImage *image,
|
||||||
@@ -258,5 +254,13 @@ void fpi_device_enroll_progress (FpDevice *device,
|
|||||||
gint completed_stages,
|
gint completed_stages,
|
||||||
FpPrint *print,
|
FpPrint *print,
|
||||||
GError *error);
|
GError *error);
|
||||||
|
void fpi_device_verify_report (FpDevice *device,
|
||||||
|
FpiMatchResult result,
|
||||||
|
FpPrint *print,
|
||||||
|
GError *error);
|
||||||
|
void fpi_device_identify_report (FpDevice *device,
|
||||||
|
FpPrint *match,
|
||||||
|
FpPrint *print,
|
||||||
|
GError *error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -210,7 +210,9 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
|
|||||||
else
|
else
|
||||||
result = FPI_MATCH_ERROR;
|
result = FPI_MATCH_ERROR;
|
||||||
|
|
||||||
fpi_device_verify_complete (device, result, g_steal_pointer (&print), error);
|
if (!error || error->domain == FP_DEVICE_RETRY)
|
||||||
|
fpi_device_verify_report (device, result, g_steal_pointer (&print), g_steal_pointer (&error));
|
||||||
|
fpi_device_verify_complete (device, error);
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self);
|
||||||
}
|
}
|
||||||
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
|
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
|
||||||
@@ -226,12 +228,14 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
|
|||||||
|
|
||||||
if (fpi_print_bz3_match (template, print, priv->bz3_threshold, &error) == FPI_MATCH_SUCCESS)
|
if (fpi_print_bz3_match (template, print, priv->bz3_threshold, &error) == FPI_MATCH_SUCCESS)
|
||||||
{
|
{
|
||||||
result = g_object_ref (template);
|
result = template;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fpi_device_identify_complete (device, result, g_steal_pointer (&print), error);
|
if (!error || error->domain == FP_DEVICE_RETRY)
|
||||||
|
fpi_device_identify_report (device, result, g_steal_pointer (&print), g_steal_pointer (&error));
|
||||||
|
fpi_device_identify_complete (device, error);
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -410,12 +414,30 @@ fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
|
|||||||
priv->enroll_await_on_pending = TRUE;
|
priv->enroll_await_on_pending = TRUE;
|
||||||
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF);
|
fp_image_device_change_state (self, FPI_IMAGE_DEVICE_STATE_AWAIT_FINGER_OFF);
|
||||||
}
|
}
|
||||||
|
else if (action == FPI_DEVICE_ACTION_VERIFY)
|
||||||
|
{
|
||||||
|
fpi_device_verify_report (FP_DEVICE (self), FPI_MATCH_ERROR, NULL, error);
|
||||||
|
priv->cancelling = TRUE;
|
||||||
|
fpi_image_device_deactivate (self);
|
||||||
|
priv->cancelling = FALSE;
|
||||||
|
fpi_device_verify_complete (FP_DEVICE (self), NULL);
|
||||||
|
}
|
||||||
|
else if (action == FPI_DEVICE_ACTION_IDENTIFY)
|
||||||
|
{
|
||||||
|
fpi_device_identify_report (FP_DEVICE (self), NULL, NULL, error);
|
||||||
|
priv->cancelling = TRUE;
|
||||||
|
fpi_image_device_deactivate (self);
|
||||||
|
priv->cancelling = FALSE;
|
||||||
|
fpi_device_identify_complete (FP_DEVICE (self), NULL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We abort the operation and let the surrounding code retry in the
|
/* We abort the operation and let the surrounding code retry in the
|
||||||
* non-enroll case (this is identical to a session error). */
|
* non-enroll case (this is identical to a session error). */
|
||||||
g_debug ("Abort current operation due to retry (non-enroll case)");
|
g_debug ("Abort current operation due to retry (non-enroll case)");
|
||||||
|
priv->cancelling = TRUE;
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self);
|
||||||
|
priv->cancelling = FALSE;
|
||||||
fpi_device_action_error (FP_DEVICE (self), error);
|
fpi_device_action_error (FP_DEVICE (self), error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -426,7 +448,9 @@ fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
|
|||||||
* @error: The #GError to report
|
* @error: The #GError to report
|
||||||
*
|
*
|
||||||
* Report an error while interacting with the device. This effectively
|
* Report an error while interacting with the device. This effectively
|
||||||
* aborts the current ongoing action.
|
* aborts the current ongoing action. Note that doing so will result in
|
||||||
|
* the deactivation handler to be called and this function must not be
|
||||||
|
* used to report an error during deactivation.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_image_device_session_error (FpImageDevice *self, GError *error)
|
fpi_image_device_session_error (FpImageDevice *self, GError *error)
|
||||||
@@ -453,17 +477,29 @@ fpi_image_device_session_error (FpImageDevice *self, GError *error)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
|
||||||
|
fpi_device_action_is_cancelled (FP_DEVICE (self)))
|
||||||
|
{
|
||||||
|
/* Ignore cancellation errors here, as we will explicitly deactivate
|
||||||
|
* anyway (or, may already have done so at this point).
|
||||||
|
*/
|
||||||
|
g_debug ("Driver reported a cancellation error, this is expected but not required. Ignoring.");
|
||||||
|
g_clear_error (&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
else if (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
|
||||||
{
|
{
|
||||||
g_warning ("Driver reported session error; translating to deactivation failure.");
|
g_warning ("Driver reported session error while deactivating already, ignoring. This indicates a driver bug.");
|
||||||
fpi_image_device_deactivate_complete (self, error);
|
g_clear_error (&error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error->domain == FP_DEVICE_RETRY)
|
if (error->domain == FP_DEVICE_RETRY)
|
||||||
g_warning ("Driver should report retries using fpi_image_device_retry_scan!");
|
g_warning ("Driver should report retries using fpi_image_device_retry_scan!");
|
||||||
|
|
||||||
|
priv->cancelling = TRUE;
|
||||||
fpi_image_device_deactivate (self);
|
fpi_image_device_deactivate (self);
|
||||||
|
priv->cancelling = FALSE;
|
||||||
fpi_device_action_error (FP_DEVICE (self), error);
|
fpi_device_action_error (FP_DEVICE (self), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ insert_drivers (GList *list)
|
|||||||
for (i = 0; i < drivers->len; i++)
|
for (i = 0; i < drivers->len; i++)
|
||||||
{
|
{
|
||||||
GType driver = g_array_index (drivers, GType, i);
|
GType driver = g_array_index (drivers, GType, i);
|
||||||
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
|
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
|
|
||||||
const FpIdEntry *entry;
|
const FpIdEntry *entry;
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
|
|||||||
@@ -104,8 +104,7 @@ main (int argc, char **argv)
|
|||||||
for (i = 0; i < drivers->len; i++)
|
for (i = 0; i < drivers->len; i++)
|
||||||
{
|
{
|
||||||
GType driver = g_array_index (drivers, GType, i);
|
GType driver = g_array_index (drivers, GType, i);
|
||||||
g_autoptr(GTypeClass) type_class = g_type_class_ref (driver);
|
g_autoptr(FpDeviceClass) cls = g_type_class_ref (driver);
|
||||||
FpDeviceClass *cls = FP_DEVICE_CLASS (type_class);
|
|
||||||
|
|
||||||
if (cls->type != FP_DEVICE_TYPE_USB)
|
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ other_sources = []
|
|||||||
fp_enums = gnome.mkenums_simple('fp-enums',
|
fp_enums = gnome.mkenums_simple('fp-enums',
|
||||||
sources: libfprint_public_headers,
|
sources: libfprint_public_headers,
|
||||||
install_header: true,
|
install_header: true,
|
||||||
install_dir: get_option('includedir') / meson.project_name(),
|
install_dir: get_option('includedir') / versioned_libname,
|
||||||
)
|
)
|
||||||
fp_enums_h = fp_enums[1]
|
fp_enums_h = fp_enums[1]
|
||||||
|
|
||||||
@@ -209,6 +209,10 @@ deps = [
|
|||||||
nss_dep,
|
nss_dep,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# These are empty and only exist so that the include directories are created
|
||||||
|
# in the build tree. This silences a build time warning.
|
||||||
|
subdir('nbis/include')
|
||||||
|
subdir('nbis/libfprint-include')
|
||||||
deps += declare_dependency(include_directories: [
|
deps += declare_dependency(include_directories: [
|
||||||
root_inc,
|
root_inc,
|
||||||
include_directories('nbis/include'),
|
include_directories('nbis/include'),
|
||||||
@@ -248,7 +252,7 @@ libfprint_drivers = static_library('fprint-drivers',
|
|||||||
mapfile = files('libfprint.ver')
|
mapfile = files('libfprint.ver')
|
||||||
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0])
|
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0])
|
||||||
|
|
||||||
libfprint = library('fprint',
|
libfprint = library(versioned_libname.split('lib')[1],
|
||||||
sources: [
|
sources: [
|
||||||
fp_enums,
|
fp_enums,
|
||||||
libfprint_sources,
|
libfprint_sources,
|
||||||
@@ -272,7 +276,7 @@ libfprint_dep = declare_dependency(link_with: libfprint,
|
|||||||
])
|
])
|
||||||
|
|
||||||
install_headers(['fprint.h'] + libfprint_public_headers,
|
install_headers(['fprint.h'] + libfprint_public_headers,
|
||||||
subdir: meson.project_name()
|
subdir: versioned_libname
|
||||||
)
|
)
|
||||||
|
|
||||||
libfprint_private_dep = declare_dependency(
|
libfprint_private_dep = declare_dependency(
|
||||||
@@ -292,7 +296,7 @@ udev_rules = executable('fprint-list-udev-rules',
|
|||||||
|
|
||||||
if get_option('udev_rules')
|
if get_option('udev_rules')
|
||||||
custom_target('udev-rules',
|
custom_target('udev-rules',
|
||||||
output: '60-fprint-autosuspend.rules',
|
output: '60-@0@-autosuspend.rules'.format(versioned_libname),
|
||||||
capture: true,
|
capture: true,
|
||||||
command: [ udev_rules ],
|
command: [ udev_rules ],
|
||||||
install: true,
|
install: true,
|
||||||
|
|||||||
+8
-8
@@ -1,10 +1,10 @@
|
|||||||
project('libfprint', [ 'c', 'cpp' ],
|
project('libfprint', [ 'c', 'cpp' ],
|
||||||
version: '1.90.0',
|
version: '1.90.1',
|
||||||
license: 'LGPLv2.1+',
|
license: 'LGPLv2.1+',
|
||||||
default_options: [
|
default_options: [
|
||||||
'buildtype=debugoptimized',
|
'buildtype=debugoptimized',
|
||||||
'warning_level=1',
|
'warning_level=1',
|
||||||
'c_std=c99',
|
'c_std=gnu99',
|
||||||
],
|
],
|
||||||
meson_version: '>= 0.49.0')
|
meson_version: '>= 0.49.0')
|
||||||
|
|
||||||
@@ -53,10 +53,9 @@ common_cflags = cc.get_supported_arguments([
|
|||||||
'-DGLIB_VERSION_MIN_REQUIRED=' + glib_version_def,
|
'-DGLIB_VERSION_MIN_REQUIRED=' + glib_version_def,
|
||||||
'-DGLIB_VERSION_MAX_ALLOWED=' + glib_version_def,
|
'-DGLIB_VERSION_MAX_ALLOWED=' + glib_version_def,
|
||||||
'-D_GNU_SOURCE',
|
'-D_GNU_SOURCE',
|
||||||
'-DG_LOG_DOMAIN="libfprint"',
|
'-DG_LOG_DOMAIN="@0@"'.format(meson.project_name()),
|
||||||
])
|
])
|
||||||
c_cflags = cc.get_supported_arguments([
|
c_cflags = cc.get_supported_arguments([
|
||||||
'-std=gnu99',
|
|
||||||
'-Wimplicit-function-declaration',
|
'-Wimplicit-function-declaration',
|
||||||
'-Wmissing-prototypes',
|
'-Wmissing-prototypes',
|
||||||
'-Wnested-externs',
|
'-Wnested-externs',
|
||||||
@@ -75,11 +74,12 @@ soversion = 2
|
|||||||
current = 0
|
current = 0
|
||||||
revision = 0
|
revision = 0
|
||||||
libversion = '@0@.@1@.@2@'.format(soversion, current, revision)
|
libversion = '@0@.@1@.@2@'.format(soversion, current, revision)
|
||||||
|
versioned_libname = meson.project_name() + '-' + soversion.to_string()
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
||||||
gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
|
gio_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
|
||||||
gusb_dep = dependency('gusb', version: '>= 0.3.0')
|
gusb_dep = dependency('gusb', version: '>= 0.2.0')
|
||||||
mathlib_dep = cc.find_library('m', required: false)
|
mathlib_dep = cc.find_library('m', required: false)
|
||||||
|
|
||||||
# The following dependencies are only used for tests
|
# The following dependencies are only used for tests
|
||||||
@@ -208,10 +208,10 @@ subdir('tests')
|
|||||||
|
|
||||||
pkgconfig = import('pkgconfig')
|
pkgconfig = import('pkgconfig')
|
||||||
pkgconfig.generate(
|
pkgconfig.generate(
|
||||||
name: meson.project_name(),
|
name: versioned_libname,
|
||||||
description: 'Generic C API for fingerprint reader access',
|
description: 'Generic C API for fingerprint reader access',
|
||||||
version: meson.project_version(),
|
version: meson.project_version(),
|
||||||
libraries: libfprint,
|
libraries: libfprint,
|
||||||
subdirs: meson.project_name(),
|
subdirs: versioned_libname,
|
||||||
filebase: meson.project_name() + '@0@'.format(soversion),
|
filebase: versioned_libname,
|
||||||
)
|
)
|
||||||
|
|||||||
+28
-5
@@ -26,12 +26,35 @@ if get_option('introspection')
|
|||||||
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
|
envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint'))
|
||||||
|
|
||||||
if 'virtual_image' in drivers
|
if 'virtual_image' in drivers
|
||||||
test('virtual-image',
|
python3 = find_program('python3')
|
||||||
find_program('virtual-image.py'),
|
unittest_inspector = find_program('unittest_inspector.py')
|
||||||
args: '--verbose',
|
base_args = files('virtual-image.py')
|
||||||
env: envs,
|
suite = []
|
||||||
|
|
||||||
|
r = run_command(unittest_inspector, files('virtual-image.py'))
|
||||||
|
unit_tests = r.stdout().strip().split('\n')
|
||||||
|
|
||||||
|
if r.returncode() == 0 and unit_tests.length() > 0
|
||||||
|
suite += 'virtual-image'
|
||||||
|
else
|
||||||
|
unit_tests = ['virtual-image']
|
||||||
|
endif
|
||||||
|
|
||||||
|
foreach ut: unit_tests
|
||||||
|
ut_suite = suite
|
||||||
|
ut_args = base_args
|
||||||
|
if unit_tests.length() > 1
|
||||||
|
ut_args += ut
|
||||||
|
ut_suite += ut.split('.')[0]
|
||||||
|
endif
|
||||||
|
test(ut,
|
||||||
|
python3,
|
||||||
|
args: ut_args,
|
||||||
|
suite: ut_suite,
|
||||||
depends: libfprint_typelib,
|
depends: libfprint_typelib,
|
||||||
|
env: envs,
|
||||||
)
|
)
|
||||||
|
endforeach
|
||||||
else
|
else
|
||||||
test('virtual-image',
|
test('virtual-image',
|
||||||
find_program('sh'),
|
find_program('sh'),
|
||||||
@@ -43,7 +66,7 @@ if get_option('introspection')
|
|||||||
driver_envs = envs
|
driver_envs = envs
|
||||||
driver_envs.set('FP_DRIVERS_WHITELIST', driver_test)
|
driver_envs.set('FP_DRIVERS_WHITELIST', driver_test)
|
||||||
|
|
||||||
if driver_test in drivers
|
if driver_test in drivers and gusb_dep.version().version_compare('>= 0.3.0')
|
||||||
test(driver_test,
|
test(driver_test,
|
||||||
find_program('umockdev-test.py'),
|
find_program('umockdev-test.py'),
|
||||||
args: join_paths(meson.current_source_dir(), driver_test),
|
args: join_paths(meson.current_source_dir(), driver_test),
|
||||||
|
|||||||
+89
-19
@@ -35,9 +35,15 @@ fpi_device_fake_probe (FpDevice *device)
|
|||||||
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_probe;
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_device_probe_complete (device, dev_class->id, dev_class->full_name,
|
fpi_device_probe_complete (device, dev_class->id, dev_class->full_name,
|
||||||
fake_dev->ret_error);
|
fake_dev->ret_error);
|
||||||
}
|
}
|
||||||
@@ -47,9 +53,15 @@ fpi_device_fake_open (FpDevice *device)
|
|||||||
{
|
{
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
|
fake_dev->last_called_function = fpi_device_fake_open;
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_OPEN);
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_OPEN);
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_open;
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_device_open_complete (device, fake_dev->ret_error);
|
fpi_device_open_complete (device, fake_dev->ret_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +70,15 @@ fpi_device_fake_close (FpDevice *device)
|
|||||||
{
|
{
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
|
fake_dev->last_called_function = fpi_device_fake_close;
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_CLOSE);
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_CLOSE);
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_close;
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_device_close_complete (device, fake_dev->ret_error);
|
fpi_device_close_complete (device, fake_dev->ret_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,13 +88,20 @@ fpi_device_fake_enroll (FpDevice *device)
|
|||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
FpPrint *print = fake_dev->ret_print;
|
FpPrint *print = fake_dev->ret_print;
|
||||||
|
|
||||||
|
fake_dev->last_called_function = fpi_device_fake_enroll;
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_ENROLL);
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_ENROLL);
|
||||||
|
|
||||||
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_device_get_enroll_data (device, (FpPrint **) &fake_dev->action_data);
|
fpi_device_get_enroll_data (device, (FpPrint **) &fake_dev->action_data);
|
||||||
|
|
||||||
if (!print && !fake_dev->ret_error)
|
if (!print && !fake_dev->ret_error)
|
||||||
fpi_device_get_enroll_data (device, &print);
|
fpi_device_get_enroll_data (device, &print);
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_enroll;
|
|
||||||
fpi_device_enroll_complete (device,
|
fpi_device_enroll_complete (device,
|
||||||
print ? g_object_ref (print) : NULL,
|
print ? g_object_ref (print) : NULL,
|
||||||
fake_dev->ret_error);
|
fake_dev->ret_error);
|
||||||
@@ -88,15 +113,29 @@ fpi_device_fake_verify (FpDevice *device)
|
|||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
FpPrint *print = fake_dev->ret_print;
|
FpPrint *print = fake_dev->ret_print;
|
||||||
|
|
||||||
|
fake_dev->last_called_function = fpi_device_fake_verify;
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_VERIFY);
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_VERIFY);
|
||||||
|
|
||||||
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_device_get_verify_data (device, (FpPrint **) &fake_dev->action_data);
|
fpi_device_get_verify_data (device, (FpPrint **) &fake_dev->action_data);
|
||||||
|
|
||||||
if (!print && !fake_dev->ret_error)
|
if (!print && !fake_dev->ret_error)
|
||||||
fpi_device_get_verify_data (device, &print);
|
fpi_device_get_verify_data (device, &print);
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_verify;
|
if (!fake_dev->ret_error || fake_dev->ret_error->domain == FP_DEVICE_RETRY)
|
||||||
fpi_device_verify_complete (device, fake_dev->ret_result, print,
|
{
|
||||||
fake_dev->ret_error);
|
fpi_device_verify_report (device, fake_dev->ret_result, print, fake_dev->ret_error);
|
||||||
|
fpi_device_verify_complete (device, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_device_verify_complete (device, fake_dev->ret_error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -105,7 +144,15 @@ fpi_device_fake_identify (FpDevice *device)
|
|||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
FpPrint *match = fake_dev->ret_match;
|
FpPrint *match = fake_dev->ret_match;
|
||||||
|
|
||||||
|
fake_dev->last_called_function = fpi_device_fake_identify;
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_IDENTIFY);
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_IDENTIFY);
|
||||||
|
|
||||||
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_device_get_identify_data (device, (GPtrArray **) &fake_dev->action_data);
|
fpi_device_get_identify_data (device, (GPtrArray **) &fake_dev->action_data);
|
||||||
|
|
||||||
if (!match && !fake_dev->ret_error)
|
if (!match && !fake_dev->ret_error)
|
||||||
@@ -127,9 +174,15 @@ fpi_device_fake_identify (FpDevice *device)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_identify;
|
if (!fake_dev->ret_error || fake_dev->ret_error->domain == FP_DEVICE_RETRY)
|
||||||
fpi_device_identify_complete (device, match, fake_dev->ret_print,
|
{
|
||||||
fake_dev->ret_error);
|
fpi_device_identify_report (device, match, fake_dev->ret_print, fake_dev->ret_error);
|
||||||
|
fpi_device_identify_complete (device, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fpi_device_identify_complete (device, fake_dev->ret_error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -137,10 +190,16 @@ fpi_device_fake_capture (FpDevice *device)
|
|||||||
{
|
{
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_CAPTURE);
|
|
||||||
fpi_device_get_capture_data (device, (gboolean *) &fake_dev->action_data);
|
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_capture;
|
fake_dev->last_called_function = fpi_device_fake_capture;
|
||||||
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_CAPTURE);
|
||||||
|
|
||||||
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_device_get_capture_data (device, (gboolean *) &fake_dev->action_data);
|
||||||
fpi_device_capture_complete (device, fake_dev->ret_image, fake_dev->ret_error);
|
fpi_device_capture_complete (device, fake_dev->ret_image, fake_dev->ret_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,9 +208,15 @@ fpi_device_fake_list (FpDevice *device)
|
|||||||
{
|
{
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
|
fake_dev->last_called_function = fpi_device_fake_list;
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_LIST);
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_LIST);
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_list;
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpi_device_list_complete (device, fake_dev->ret_list, fake_dev->ret_error);
|
fpi_device_list_complete (device, fake_dev->ret_list, fake_dev->ret_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,10 +225,16 @@ fpi_device_fake_delete (FpDevice *device)
|
|||||||
{
|
{
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_DELETE);
|
|
||||||
fpi_device_get_delete_data (device, (gpointer) & fake_dev->action_data);
|
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_delete;
|
fake_dev->last_called_function = fpi_device_fake_delete;
|
||||||
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_DELETE);
|
||||||
|
|
||||||
|
if (fake_dev->return_action_error)
|
||||||
|
{
|
||||||
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fpi_device_get_delete_data (device, (gpointer) (&fake_dev->action_data));
|
||||||
fpi_device_delete_complete (device, fake_dev->ret_error);
|
fpi_device_delete_complete (device, fake_dev->ret_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,9 +243,8 @@ fpi_device_fake_cancel (FpDevice *device)
|
|||||||
{
|
{
|
||||||
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), !=, FPI_DEVICE_ACTION_NONE);
|
|
||||||
|
|
||||||
fake_dev->last_called_function = fpi_device_fake_cancel;
|
fake_dev->last_called_function = fpi_device_fake_cancel;
|
||||||
|
g_assert_cmpuint (fpi_device_get_current_action (device), !=, FPI_DEVICE_ACTION_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ struct _FpiDeviceFake
|
|||||||
FpDevice parent;
|
FpDevice parent;
|
||||||
|
|
||||||
gpointer last_called_function;
|
gpointer last_called_function;
|
||||||
|
gboolean return_action_error;
|
||||||
|
|
||||||
GError *ret_error;
|
GError *ret_error;
|
||||||
FpPrint *ret_print;
|
FpPrint *ret_print;
|
||||||
|
|||||||
+905
-62
File diff suppressed because it is too large
Load Diff
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
# Copyright © 2020, Canonical Ltd
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2.1 of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public
|
||||||
|
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
# Authors:
|
||||||
|
# Marco Trevisan <marco.trevisan@canonical.com>
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import importlib.util
|
||||||
|
import inspect
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
def list_tests(module):
|
||||||
|
tests = []
|
||||||
|
for name, obj in inspect.getmembers(module):
|
||||||
|
if inspect.isclass(obj) and issubclass(obj, unittest.TestCase):
|
||||||
|
cases = unittest.defaultTestLoader.getTestCaseNames(obj)
|
||||||
|
tests += [ (obj, '{}.{}'.format(name, t)) for t in cases ]
|
||||||
|
return tests
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('unittest_source', type=argparse.FileType('r'))
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
source_path = args.unittest_source.name
|
||||||
|
spec = importlib.util.spec_from_file_location(
|
||||||
|
os.path.basename(source_path), source_path)
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
|
||||||
|
for machine, human in list_tests(module):
|
||||||
|
print(human)
|
||||||
+78
-37
@@ -1,20 +1,24 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
import gi
|
|
||||||
gi.require_version('FPrint', '2.0')
|
|
||||||
from gi.repository import FPrint, GLib, Gio
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
try:
|
||||||
import socket
|
import gi
|
||||||
import struct
|
gi.require_version('FPrint', '2.0')
|
||||||
import subprocess
|
from gi.repository import FPrint, GLib, Gio
|
||||||
import shutil
|
|
||||||
import glob
|
import os
|
||||||
import cairo
|
import sys
|
||||||
import tempfile
|
import unittest
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
import glob
|
||||||
|
import cairo
|
||||||
|
import tempfile
|
||||||
|
except Exception as e:
|
||||||
|
print("Missing dependencies: %s" % str(e))
|
||||||
|
sys.exit(77)
|
||||||
|
|
||||||
# Re-run the test with the passed wrapper if set
|
# Re-run the test with the passed wrapper if set
|
||||||
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
|
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
|
||||||
@@ -97,15 +101,13 @@ class VirtualImage(unittest.TestCase):
|
|||||||
del self.con
|
del self.con
|
||||||
self.dev.close_sync()
|
self.dev.close_sync()
|
||||||
|
|
||||||
def send_retry(self, retry_error=1, iterate=True):
|
def send_retry(self, retry_error=FPrint.DeviceRetry.TOO_SHORT, iterate=True):
|
||||||
# The default (1) is too-short
|
self.con.sendall(struct.pack('ii', -1, retry_error))
|
||||||
self.sendall(struct.pack('ii', -1, retry_error))
|
|
||||||
while iterate and ctx.pending():
|
while iterate and ctx.pending():
|
||||||
ctx.iteration(False)
|
ctx.iteration(False)
|
||||||
|
|
||||||
def send_error(self, device_error=0, iterate=True):
|
def send_error(self, device_error=FPrint.DeviceError.GENERAL, iterate=True):
|
||||||
# The default (0) is a generic error
|
self.con.sendall(struct.pack('ii', -2, device_error))
|
||||||
self.sendall(struct.pack('ii', -1, retry_error))
|
|
||||||
while iterate and ctx.pending():
|
while iterate and ctx.pending():
|
||||||
ctx.iteration(False)
|
ctx.iteration(False)
|
||||||
|
|
||||||
@@ -212,15 +214,16 @@ class VirtualImage(unittest.TestCase):
|
|||||||
done = False
|
done = False
|
||||||
|
|
||||||
def verify_cb(dev, res):
|
def verify_cb(dev, res):
|
||||||
match, fp = dev.verify_finish(res)
|
try:
|
||||||
self._verify_match = match
|
self._verify_match, self._verify_fp = dev.verify_finish(res)
|
||||||
self._verify_fp = fp
|
except gi.repository.GLib.Error as e:
|
||||||
|
self._verify_error = e
|
||||||
|
|
||||||
fp_whorl = self.enroll_print('whorl')
|
fp_whorl = self.enroll_print('whorl')
|
||||||
|
|
||||||
self._verify_match = None
|
self._verify_match = None
|
||||||
self._verify_fp = None
|
self._verify_fp = None
|
||||||
self.dev.verify(fp_whorl, None, verify_cb)
|
self.dev.verify(fp_whorl, callback=verify_cb)
|
||||||
self.send_image('whorl')
|
self.send_image('whorl')
|
||||||
while self._verify_match is None:
|
while self._verify_match is None:
|
||||||
ctx.iteration(True)
|
ctx.iteration(True)
|
||||||
@@ -228,41 +231,79 @@ class VirtualImage(unittest.TestCase):
|
|||||||
|
|
||||||
self._verify_match = None
|
self._verify_match = None
|
||||||
self._verify_fp = None
|
self._verify_fp = None
|
||||||
self.dev.verify(fp_whorl, None, verify_cb)
|
self.dev.verify(fp_whorl, callback=verify_cb)
|
||||||
self.send_image('tented_arch')
|
self.send_image('tented_arch')
|
||||||
while self._verify_match is None:
|
while self._verify_match is None:
|
||||||
ctx.iteration(True)
|
ctx.iteration(True)
|
||||||
assert(not self._verify_match)
|
assert(not self._verify_match)
|
||||||
|
|
||||||
|
# Test verify error cases
|
||||||
|
self._verify_fp = None
|
||||||
|
self._verify_error = None
|
||||||
|
self.dev.verify(fp_whorl, callback=verify_cb)
|
||||||
|
self.send_retry()
|
||||||
|
while self._verify_fp is None and self._verify_error is None:
|
||||||
|
ctx.iteration(True)
|
||||||
|
assert(self._verify_error is not None)
|
||||||
|
assert(self._verify_error.matches(FPrint.device_retry_quark(), FPrint.DeviceRetry.TOO_SHORT))
|
||||||
|
|
||||||
|
self._verify_fp = None
|
||||||
|
self._verify_error = None
|
||||||
|
self.dev.verify(fp_whorl, callback=verify_cb)
|
||||||
|
self.send_error()
|
||||||
|
while self._verify_fp is None and self._verify_error is None:
|
||||||
|
ctx.iteration(True)
|
||||||
|
assert(self._verify_error is not None)
|
||||||
|
print(self._verify_error)
|
||||||
|
assert(self._verify_error.matches(FPrint.device_error_quark(), FPrint.DeviceError.GENERAL))
|
||||||
|
|
||||||
def test_identify(self):
|
def test_identify(self):
|
||||||
done = False
|
done = False
|
||||||
|
|
||||||
def verify_cb(dev, res):
|
|
||||||
r, fp = dev.verify_finish(res)
|
|
||||||
self._verify_match = r
|
|
||||||
self._verify_fp = fp
|
|
||||||
|
|
||||||
fp_whorl = self.enroll_print('whorl')
|
fp_whorl = self.enroll_print('whorl')
|
||||||
fp_tented_arch = self.enroll_print('tented_arch')
|
fp_tented_arch = self.enroll_print('tented_arch')
|
||||||
|
|
||||||
def identify_cb(dev, res):
|
def identify_cb(dev, res):
|
||||||
print('Identify finished')
|
print('Identify finished')
|
||||||
|
try:
|
||||||
self._identify_match, self._identify_fp = self.dev.identify_finish(res)
|
self._identify_match, self._identify_fp = self.dev.identify_finish(res)
|
||||||
|
except gi.repository.GLib.Error as e:
|
||||||
|
print(e)
|
||||||
|
self._identify_error = e
|
||||||
|
|
||||||
self._identify_fp = None
|
self._identify_fp = None
|
||||||
self.dev.identify([fp_whorl, fp_tented_arch], None, identify_cb)
|
self.dev.identify([fp_whorl, fp_tented_arch], callback=identify_cb)
|
||||||
self.send_image('tented_arch')
|
self.send_image('tented_arch')
|
||||||
while self._identify_fp is None:
|
while self._identify_fp is None:
|
||||||
ctx.iteration(True)
|
ctx.iteration(True)
|
||||||
assert(self._identify_match is fp_tented_arch)
|
assert(self._identify_match is fp_tented_arch)
|
||||||
|
|
||||||
self._identify_fp = None
|
self._identify_fp = None
|
||||||
self.dev.identify([fp_whorl, fp_tented_arch], None, identify_cb)
|
self.dev.identify([fp_whorl, fp_tented_arch], callback=identify_cb)
|
||||||
self.send_image('whorl')
|
self.send_image('whorl')
|
||||||
while self._identify_fp is None:
|
while self._identify_fp is None:
|
||||||
ctx.iteration(True)
|
ctx.iteration(True)
|
||||||
assert(self._identify_match is fp_whorl)
|
assert(self._identify_match is fp_whorl)
|
||||||
|
|
||||||
|
# Test error cases
|
||||||
|
self._identify_fp = None
|
||||||
|
self._identify_error = None
|
||||||
|
self.dev.identify([fp_whorl, fp_tented_arch], callback=identify_cb)
|
||||||
|
self.send_retry()
|
||||||
|
while self._identify_fp is None and self._identify_error is None:
|
||||||
|
ctx.iteration(True)
|
||||||
|
assert(self._identify_error is not None)
|
||||||
|
assert(self._identify_error.matches(FPrint.device_retry_quark(), FPrint.DeviceRetry.TOO_SHORT))
|
||||||
|
|
||||||
|
self._identify_fp = None
|
||||||
|
self._identify_error = None
|
||||||
|
self.dev.identify([fp_whorl, fp_tented_arch], callback=identify_cb)
|
||||||
|
self.send_error()
|
||||||
|
while self._identify_fp is None and self._identify_error is None:
|
||||||
|
ctx.iteration(True)
|
||||||
|
assert(self._identify_error is not None)
|
||||||
|
assert(self._identify_error.matches(FPrint.device_error_quark(), FPrint.DeviceError.GENERAL))
|
||||||
|
|
||||||
def test_verify_serialized(self):
|
def test_verify_serialized(self):
|
||||||
done = False
|
done = False
|
||||||
|
|
||||||
@@ -290,7 +331,7 @@ class VirtualImage(unittest.TestCase):
|
|||||||
|
|
||||||
self._verify_match = None
|
self._verify_match = None
|
||||||
self._verify_fp = None
|
self._verify_fp = None
|
||||||
self.dev.verify(fp_whorl_new, None, verify_cb)
|
self.dev.verify(fp_whorl_new, callback=verify_cb)
|
||||||
self.send_image('whorl')
|
self.send_image('whorl')
|
||||||
while self._verify_match is None:
|
while self._verify_match is None:
|
||||||
ctx.iteration(True)
|
ctx.iteration(True)
|
||||||
@@ -298,12 +339,12 @@ class VirtualImage(unittest.TestCase):
|
|||||||
|
|
||||||
self._verify_match = None
|
self._verify_match = None
|
||||||
self._verify_fp = None
|
self._verify_fp = None
|
||||||
self.dev.verify(fp_whorl_new, None, verify_cb)
|
self.dev.verify(fp_whorl_new, callback=verify_cb)
|
||||||
self.send_image('tented_arch')
|
self.send_image('tented_arch')
|
||||||
while self._verify_match is None:
|
while self._verify_match is None:
|
||||||
ctx.iteration(True)
|
ctx.iteration(True)
|
||||||
assert(not self._verify_match)
|
assert(not self._verify_match)
|
||||||
|
|
||||||
# avoid writing to stderr
|
if __name__ == '__main__':
|
||||||
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
|
# avoid writing to stderr
|
||||||
|
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
|
||||||
|
|||||||
Reference in New Issue
Block a user