mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-06-11 02:28:05 +00:00
Update upstream source from tag 'upstream/1.90.1+tod1'
Update to upstream version '1.90.1+tod1'
with Debian dir c02802d539
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
*.o
|
||||
*.swp
|
||||
_build
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
include:
|
||||
- local: '.gitlab-ci/libfprint-templates.yaml'
|
||||
- project: 'wayland/ci-templates'
|
||||
ref: master
|
||||
file: '/templates/fedora.yml'
|
||||
|
||||
variables:
|
||||
extends: .libfprint_common_variables
|
||||
FEDORA_TAG: rawhide
|
||||
FEDORA_VERSION: rawhide
|
||||
FEDORA_IMAGE: "$CI_REGISTRY/libfprint/$CI_PROJECT_NAME/fedora/$FEDORA_VERSION:$FEDORA_TAG"
|
||||
BUNDLE: "org.freedesktop.libfprint.Demo.flatpak"
|
||||
LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546"
|
||||
|
||||
stages:
|
||||
- check-source
|
||||
- build
|
||||
- test
|
||||
- flatpack
|
||||
|
||||
image: "$FEDORA_IMAGE"
|
||||
|
||||
.build_one_driver_template: &build_one_driver
|
||||
script:
|
||||
# Build with a driver that doesn't need imaging, or nss
|
||||
- meson --werror -Ddrivers=$driver . _build
|
||||
- ninja -C _build
|
||||
- rm -rf _build/
|
||||
|
||||
.build_template: &build
|
||||
script:
|
||||
# And build with everything
|
||||
- meson --werror -Ddrivers=all . _build
|
||||
- ninja -C _build
|
||||
- ninja -C _build install
|
||||
|
||||
.build_template: &check_abi
|
||||
script:
|
||||
- ./.ci/check-abi ${LAST_ABI_BREAK} $(git rev-parse HEAD)
|
||||
|
||||
build:
|
||||
stage: build
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
variables:
|
||||
driver: virtual_image
|
||||
<<: *build_one_driver
|
||||
<<: *build
|
||||
# <<: *check_abi
|
||||
|
||||
test:
|
||||
stage: test
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
script:
|
||||
- meson --werror -Ddrivers=all -Db_coverage=true . _build
|
||||
- ninja -C _build
|
||||
- meson test -C _build --verbose --no-stdsplit --timeout-multiplier 3
|
||||
- ninja -C _build coverage
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/meson-logs
|
||||
expire_in: 1 week
|
||||
|
||||
test_valgrind:
|
||||
stage: test
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
script:
|
||||
- meson -Ddrivers=all . _build
|
||||
- ninja -C _build
|
||||
- meson test -C _build --verbose --no-stdsplit --setup=valgrind
|
||||
|
||||
test_indent:
|
||||
stage: check-source
|
||||
except:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
script:
|
||||
- scripts/uncrustify.sh --check
|
||||
|
||||
.flatpak_script_template: &flatpak_script
|
||||
script:
|
||||
- flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH}
|
||||
# Make sure to keep this in sync with the Flatpak manifest, all arguments
|
||||
# are passed except the config-args because we build it ourselves
|
||||
- flatpak build app meson --prefix=/app --libdir=lib ${MESON_ARGS} _build
|
||||
- flatpak build app ninja -C _build install
|
||||
- flatpak build app rm -rf /app/include/ /app/lib/pkgconfig/
|
||||
- flatpak-builder --finish-only --repo=repo app ${MANIFEST_PATH}
|
||||
# Generate a Flatpak bundle
|
||||
- flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${DBUS_ID}
|
||||
|
||||
.flatpak_artifacts_template: &flatpak_artifacts
|
||||
artifacts:
|
||||
paths:
|
||||
- ${BUNDLE}
|
||||
when: always
|
||||
expire_in: 30 days
|
||||
|
||||
.flatpak_template: &flatpak
|
||||
<<: *flatpak_script
|
||||
<<: *flatpak_artifacts
|
||||
|
||||
.flatpak_master_template: &flatpak_master
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.32
|
||||
stage: flatpack
|
||||
variables:
|
||||
MANIFEST_PATH: "demo/org.freedesktop.libfprint.Demo.json"
|
||||
# From demo/org.freedesktop.libfprint.Demo.json
|
||||
MESON_ARGS: "-Dudev_rules=false -Dx11-examples=false -Dgtk-examples=true"
|
||||
FLATPAK_MODULE: "libfprint"
|
||||
DBUS_ID: "org.freedesktop.libfprint.Demo"
|
||||
<<: *flatpak
|
||||
|
||||
flatpak-auto master:
|
||||
<<: *flatpak_master
|
||||
when: always
|
||||
only:
|
||||
- tags
|
||||
- master
|
||||
|
||||
flatpak-manual master:
|
||||
<<: *flatpak_master
|
||||
when: manual
|
||||
except:
|
||||
refs:
|
||||
- tags
|
||||
- master
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule"
|
||||
|
||||
# CONTAINERS creation stage
|
||||
container_fedora_build:
|
||||
extends: .fedora@container-build
|
||||
only:
|
||||
variables:
|
||||
- $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES"
|
||||
variables:
|
||||
GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
|
||||
# a list of packages to install
|
||||
FEDORA_RPMS: $LIBFPRINT_DEPENDENCIES
|
||||
@@ -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
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
### libfprint-TOD v1
|
||||
|
||||
- First public release
|
||||
- Based on [libfprint 1.90.1](https://gitlab.freedesktop.org/libfprint/libfprint/-/releases#v1.90.1)
|
||||
- Bumped TOD version to 1
|
||||
|
||||
### Highlights of the Drivers API changes
|
||||
|
||||
Both the driver and external APIs have changed, as both the verify and the identify functions now have early reporting mechanisms.
|
||||
|
||||
- Added API for early report of matching results or retry errors
|
||||
- Verify and identification completion functions have been simplified
|
||||
- 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 required changes
|
||||
As per the early report mechanism, drivers need to adapt, in particular:
|
||||
- New pkg-config dependency name is `libfprint-2-tod-1`
|
||||
- Verification and Identification API for non-image drivers has changed and drivers need to both `report` the result of the action and complete it:
|
||||
- `fpi_device_{verify,identify}_report` must inform whether a match/no-match or identification happened or report a *retry error*.
|
||||
- `fpi_device_{verify,identify}_complete` must be called once the device has completed the verification / identification process, in case reporting device errors (not retry ones!)
|
||||
|
||||
You can see examples of changes needed in the [reference example driver](https://gitlab.freedesktop.org/3v1n0/libfprint-tod-example-driver/-/commit/8308f84f7d1cfd1b9ed0936c13c73b43a4a46772) or the [upstream synaptics driver](https://gitlab.freedesktop.org/libfprint/libfprint/-/merge_requests/112/diffs)
|
||||
@@ -0,0 +1,9 @@
|
||||
### libfprint-TOD - libfprint for Touch OEM Drivers
|
||||
|
||||
This is a light fork of libfprint to expose internal Drivers API in order to
|
||||
create drivers as shared libraries.
|
||||
|
||||
Fork is hosted at: https://gitlab.freedesktop.org/3v1n0/libfprint/tree/tod
|
||||
|
||||
An example driver implementation is available:
|
||||
- https://gitlab.freedesktop.org/3v1n0/libfprint-tod-example-driver
|
||||
@@ -24,6 +24,11 @@
|
||||
#include "fpi-device.h"
|
||||
#include <gusb.h>
|
||||
|
||||
#include <config.h>
|
||||
#ifdef HAVE_LIBFPRINT_TOD
|
||||
#include "tod/tod-shared-loader.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SECTION: fp-context
|
||||
* @title: FpContext
|
||||
@@ -214,6 +219,8 @@ fp_context_finalize (GObject *object)
|
||||
g_object_run_dispose (G_OBJECT (priv->usb_ctx));
|
||||
g_clear_object (&priv->usb_ctx);
|
||||
|
||||
fpi_tod_shared_drivers_unregister ();
|
||||
|
||||
G_OBJECT_CLASS (fp_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -265,11 +272,16 @@ static void
|
||||
fp_context_init (FpContext *self)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GArray) shared_drivers = NULL;
|
||||
FpContextPrivate *priv = fp_context_get_instance_private (self);
|
||||
guint i;
|
||||
|
||||
priv->drivers = fpi_get_driver_types ();
|
||||
|
||||
fpi_tod_shared_drivers_register ();
|
||||
shared_drivers = fpi_tod_shared_drivers_get ();
|
||||
g_array_prepend_vals (priv->drivers, shared_drivers->data, shared_drivers->len);
|
||||
|
||||
if (get_drivers_whitelist_env ())
|
||||
{
|
||||
for (i = 0; i < priv->drivers->len;)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "fpi-image.h"
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include <config.h>
|
||||
#include <nbis.h>
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,6 +110,7 @@ struct fpi_line_asmbl_ctx
|
||||
unsigned char (*get_pixel)(struct fpi_line_asmbl_ctx *ctx,
|
||||
GSList *line,
|
||||
unsigned int x);
|
||||
gpointer _padding_dummy[32];
|
||||
};
|
||||
|
||||
FpImage *fpi_assemble_lines (struct fpi_line_asmbl_ctx *ctx,
|
||||
|
||||
@@ -45,6 +45,10 @@ struct _FpIdEntry
|
||||
const gchar *virtual_envvar;
|
||||
};
|
||||
guint64 driver_data;
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[16];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -129,6 +133,10 @@ struct _FpDeviceClass
|
||||
void (*delete) (FpDevice * device);
|
||||
|
||||
void (*cancel) (FpDevice *device);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[32];
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -93,6 +93,10 @@ struct _FpImageDeviceClass
|
||||
void (*change_state) (FpImageDevice *dev,
|
||||
FpiImageDeviceState state);
|
||||
void (*deactivate) (FpImageDevice *dev);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[32];
|
||||
};
|
||||
|
||||
void fpi_image_device_set_bz3_threshold (FpImageDevice *self,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "fpi-log.h"
|
||||
|
||||
#include <nbis.h>
|
||||
#include <config.h>
|
||||
|
||||
#if HAVE_PIXMAN
|
||||
#include <pixman.h>
|
||||
@@ -108,12 +109,12 @@ fpi_mean_sq_diff_norm (const guint8 *buf1,
|
||||
return res / size;
|
||||
}
|
||||
|
||||
#if HAVE_PIXMAN
|
||||
FpImage *
|
||||
fpi_image_resize (FpImage *orig_img,
|
||||
guint w_factor,
|
||||
guint h_factor)
|
||||
{
|
||||
#if HAVE_PIXMAN
|
||||
int new_width = orig_img->width * w_factor;
|
||||
int new_height = orig_img->height * h_factor;
|
||||
pixman_image_t *orig, *resized;
|
||||
@@ -146,5 +147,9 @@ fpi_image_resize (FpImage *orig_img,
|
||||
pixman_image_unref (resized);
|
||||
|
||||
return newimg;
|
||||
}
|
||||
#else
|
||||
fp_err ("Libfprint compiled without pixman support, impossible to resize");
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <config.h>
|
||||
#include "fp-image.h"
|
||||
|
||||
/**
|
||||
@@ -76,8 +75,6 @@ gint fpi_mean_sq_diff_norm (const guint8 *buf1,
|
||||
const guint8 *buf2,
|
||||
gint size);
|
||||
|
||||
#if HAVE_PIXMAN
|
||||
FpImage *fpi_image_resize (FpImage *orig,
|
||||
guint w_factor,
|
||||
guint h_factor);
|
||||
#endif
|
||||
|
||||
@@ -101,6 +101,10 @@ struct _FpiUsbTransfer
|
||||
|
||||
/* Data free function */
|
||||
GDestroyNotify free_buffer;
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[32];
|
||||
};
|
||||
|
||||
GType fpi_usb_transfer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
@@ -31,6 +31,7 @@ libfprint_private_headers = [
|
||||
'fpi-byte-reader.h',
|
||||
'fpi-byte-utils.h',
|
||||
'fpi-byte-writer.h',
|
||||
'fpi-compat.h',
|
||||
'fpi-context.h',
|
||||
'fpi-device.h',
|
||||
'fpi-image-device.h',
|
||||
@@ -238,6 +239,10 @@ libfprint_private = static_library('fprint-private',
|
||||
link_with: libnbis,
|
||||
install: false)
|
||||
|
||||
if get_option('tod')
|
||||
subdir('tod')
|
||||
endif
|
||||
|
||||
libfprint_drivers = static_library('fprint-drivers',
|
||||
sources: drivers_sources,
|
||||
c_args: drivers_cflags,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
LIBFPRINT_TOD_1.0.0 {
|
||||
global:
|
||||
fpi_*;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
tod_soversion = 1
|
||||
tod_subpath = versioned_libname / 'tod-@0@'.format(tod_soversion)
|
||||
tod_modules_prefix = get_option('libdir') / tod_subpath
|
||||
|
||||
tod_conf = configuration_data()
|
||||
tod_conf.set_quoted('TOD_DRIVERS_DIR',
|
||||
get_option('prefix') / get_option('libdir') / tod_subpath)
|
||||
configure_file(output: 'tod-config.h', configuration: tod_conf)
|
||||
|
||||
gmodule_dep = dependency('gmodule-2.0', version: '>=' + glib_min_version)
|
||||
deps += gmodule_dep
|
||||
|
||||
mapfile = files('libfprint-tod.ver')
|
||||
|
||||
libfprint_tod_private = static_library('fprint-tod-private',
|
||||
sources: [
|
||||
'tod-shared-loader.c',
|
||||
],
|
||||
include_directories: include_directories('..'),
|
||||
link_with: libfprint_private,
|
||||
dependencies: deps,
|
||||
install: false,
|
||||
)
|
||||
|
||||
tod_sources = []
|
||||
foreach source: libfprint_private_sources
|
||||
tod_sources += '..' / source
|
||||
endforeach
|
||||
|
||||
libfprint_tod = library(versioned_libname.split('lib')[1] + '-tod',
|
||||
sources: [
|
||||
tod_sources,
|
||||
],
|
||||
soversion: tod_soversion,
|
||||
include_directories: include_directories('..'),
|
||||
link_args: [
|
||||
'-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0]),
|
||||
'-Wl,--unresolved-symbols=ignore-in-object-files'
|
||||
],
|
||||
link_depends: mapfile,
|
||||
link_with: [libfprint_private],
|
||||
dependencies: deps,
|
||||
install: true)
|
||||
|
||||
deps += declare_dependency(
|
||||
link_with: [
|
||||
libfprint_tod,
|
||||
libfprint_tod_private,
|
||||
]
|
||||
)
|
||||
|
||||
pkgconfig = import('pkgconfig')
|
||||
pkgconfig.generate(libfprint_tod,
|
||||
name: versioned_libname + '-tod',
|
||||
filebase: '@0@-tod-@1@'.format(versioned_libname, tod_soversion),
|
||||
description: 'Private Libfprint Touch Drivers API',
|
||||
version: meson.project_version() + '+tod@0@'.format(tod_soversion),
|
||||
subdirs: tod_subpath,
|
||||
requires_private: [
|
||||
versioned_libname,
|
||||
],
|
||||
variables: [
|
||||
'tod_driversdir=${libdir}/@0@'.format(tod_subpath)
|
||||
]
|
||||
)
|
||||
|
||||
tod_headers = []
|
||||
extra_libfprint_headers = [
|
||||
'drivers_api.h',
|
||||
]
|
||||
|
||||
foreach header: libfprint_private_headers + extra_libfprint_headers
|
||||
tod_headers += '..' / header
|
||||
endforeach
|
||||
|
||||
custom_target('tod_fpi_enums_headers',
|
||||
depends: fpi_enums,
|
||||
input: fpi_enums_h,
|
||||
output: 'fpi-enums.h',
|
||||
command: ['cp', '@INPUT@', '-v', '@OUTPUT@'],
|
||||
install: true,
|
||||
install_dir: get_option('includedir') / tod_subpath)
|
||||
|
||||
install_headers(tod_headers,
|
||||
subdir: tod_subpath
|
||||
)
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Shared library loader for libfprint
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.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
|
||||
*/
|
||||
|
||||
#define FP_COMPONENT "tod"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "tod-shared-loader.h"
|
||||
#include "fpi-device.h"
|
||||
#include "fpi-log.h"
|
||||
#include "tod-config.h"
|
||||
|
||||
#define FPI_TOD_ENTRY_GTYPE_GETTER "fpi_tod_shared_driver_get_type"
|
||||
|
||||
static GArray *shared_drivers = NULL;
|
||||
static GList *shared_modules = NULL;
|
||||
|
||||
typedef GModule FpiTodModule;
|
||||
typedef GType (*FpiTodShardDriverTypeGetter) (void);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpiTodModule, g_module_close);
|
||||
|
||||
static const char *
|
||||
get_tod_drivers_dir (void)
|
||||
{
|
||||
const char *tod_env_path = g_getenv ("FP_TOD_DRIVERS_DIR");
|
||||
|
||||
if (!tod_env_path || *tod_env_path == '\0')
|
||||
return TOD_DRIVERS_DIR;
|
||||
|
||||
return tod_env_path;
|
||||
}
|
||||
|
||||
void
|
||||
fpi_tod_shared_drivers_register (void)
|
||||
{
|
||||
const char *dirname;
|
||||
const char *basename;
|
||||
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GDir) dir = NULL;
|
||||
gpointer symbol;
|
||||
|
||||
g_assert_null (shared_drivers);
|
||||
|
||||
dirname = get_tod_drivers_dir ();
|
||||
dir = g_dir_open (dirname, 0, &error);
|
||||
|
||||
shared_drivers = g_array_new (TRUE, FALSE, sizeof (GType));
|
||||
|
||||
if (error)
|
||||
{
|
||||
fp_dbg ("Impossible to load the shared drivers dir %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((basename = g_dir_read_name (dir)) != NULL)
|
||||
{
|
||||
g_autoptr(FpiTodModule) module = NULL;
|
||||
g_autoptr(GTypeClass) type_class = NULL;
|
||||
g_autofree char *module_path = NULL;
|
||||
FpiTodShardDriverTypeGetter type_getter;
|
||||
FpDeviceClass *cls;
|
||||
GType driver;
|
||||
|
||||
if (!g_str_has_prefix (basename, "lib"))
|
||||
continue;
|
||||
|
||||
if (!g_str_has_suffix (basename, ".so"))
|
||||
continue;
|
||||
|
||||
module_path = g_build_filename (dirname, basename, NULL);
|
||||
|
||||
if (!g_file_test (module_path, G_FILE_TEST_IS_REGULAR))
|
||||
continue;
|
||||
|
||||
fp_dbg ("Opening driver %s", module_path);
|
||||
|
||||
module = g_module_open (module_path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
|
||||
if (!module)
|
||||
{
|
||||
fp_err ("Impossible to load module %s: %s", module_path,
|
||||
g_module_error ());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_module_symbol (module, FPI_TOD_ENTRY_GTYPE_GETTER, &symbol))
|
||||
{
|
||||
fp_err ("Library %s doesn't expose the required entry point symbol",
|
||||
module_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
type_getter = symbol;
|
||||
driver = type_getter ();
|
||||
fp_dbg ("Found TOD entry point symbol %p, GType is %lu", symbol, driver);
|
||||
|
||||
if (!G_TYPE_IS_OBJECT (driver) || !g_type_is_a (driver, FP_TYPE_DEVICE))
|
||||
{
|
||||
fp_err ("Library %s returned GType (%lu) doesn't represent a device",
|
||||
module_path, driver);
|
||||
continue;
|
||||
}
|
||||
|
||||
type_class = g_type_class_ref (driver);
|
||||
g_assert_true (g_type_check_class_is_a (type_class, FP_TYPE_DEVICE));
|
||||
|
||||
cls = FP_DEVICE_CLASS (type_class);
|
||||
|
||||
fp_dbg ("Loading driver %s (%s)", cls->id, cls->full_name);
|
||||
g_array_append_val (shared_drivers, driver);
|
||||
|
||||
shared_modules = g_list_prepend (shared_modules,
|
||||
g_steal_pointer (&module));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fpi_tod_shared_drivers_unregister (void)
|
||||
{
|
||||
g_clear_pointer (&shared_drivers, g_array_unref);
|
||||
|
||||
if (g_strcmp0 (g_getenv ("FP_TOD_KEEP_MODULES_OPEN"), "TRUE") != 0)
|
||||
{
|
||||
g_list_free_full (shared_modules, (GDestroyNotify) g_module_close);
|
||||
shared_modules = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
GArray *
|
||||
fpi_tod_shared_drivers_get (void)
|
||||
{
|
||||
return g_array_ref (shared_drivers);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Shared library loader for libfprint
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.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.h>
|
||||
|
||||
|
||||
void fpi_tod_shared_drivers_register (void);
|
||||
void fpi_tod_shared_drivers_unregister (void);
|
||||
|
||||
GArray *fpi_tod_shared_drivers_get (void);
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
project('libfprint', [ 'c', 'cpp' ],
|
||||
version: '1.90.1',
|
||||
version: '1.90.1+tod1',
|
||||
license: 'LGPLv2.1+',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
@@ -190,6 +190,8 @@ if get_option('gtk-examples')
|
||||
endif
|
||||
endif
|
||||
|
||||
libfprint_conf.set10('HAVE_LIBFPRINT_TOD', get_option('tod'))
|
||||
|
||||
configure_file(output: 'config.h', configuration: libfprint_conf)
|
||||
|
||||
subdir('libfprint')
|
||||
|
||||
@@ -22,3 +22,8 @@ option('doc',
|
||||
description: 'Whether to build the API documentation',
|
||||
type: 'boolean',
|
||||
value: true)
|
||||
|
||||
option('tod',
|
||||
description: 'Whether to build the TOD library',
|
||||
type: 'boolean',
|
||||
value: true)
|
||||
|
||||
@@ -189,3 +189,45 @@ if valgrind.found()
|
||||
valgrind.path(), glib_suppressions, python_suppressions)
|
||||
])
|
||||
endif
|
||||
|
||||
if get_option('tod')
|
||||
tod_envs = envs
|
||||
tod_envs.set('FP_TOD_DRIVERS_DIR', meson.current_build_dir())
|
||||
tod_envs.set('FP_TOD_KEEP_MODULES_OPEN', 'TRUE')
|
||||
tod_envs.set('FP_VIRTUAL_FAKE_DEVICE', 'yes')
|
||||
tod_envs.append('FP_DRIVERS_WHITELIST', 'fake_test_dev')
|
||||
|
||||
fake_driver = shared_module('device-fake-tod-driver',
|
||||
sources: [
|
||||
'test-device-fake-tod.c',
|
||||
],
|
||||
link_with: [
|
||||
test_utils,
|
||||
libfprint_tod,
|
||||
],
|
||||
include_directories: include_directories('../libfprint'),
|
||||
dependencies: deps,
|
||||
install: false
|
||||
)
|
||||
|
||||
tod_unit_tests = [
|
||||
'fp-context-tod',
|
||||
'fp-device-tod',
|
||||
]
|
||||
|
||||
foreach test_name: tod_unit_tests
|
||||
basename = 'test-' + test_name
|
||||
test_exe = executable(basename,
|
||||
sources: basename + '.c',
|
||||
dependencies: libfprint_private_dep,
|
||||
c_args: common_cflags,
|
||||
link_with: test_utils,
|
||||
)
|
||||
test(test_name,
|
||||
find_program('test-runner.sh'),
|
||||
suite: ['unit-tests', 'tod'],
|
||||
args: [test_exe],
|
||||
env: tod_envs,
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Virtual driver for device debugging
|
||||
*
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.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
|
||||
*/
|
||||
|
||||
#include "test-device-fake-tod.h"
|
||||
#include "test-device-fake.h"
|
||||
|
||||
GType
|
||||
fpi_tod_shared_driver_get_type (void)
|
||||
{
|
||||
return fpi_device_fake_get_type ();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Virtual driver for device debugging
|
||||
*
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.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>
|
||||
|
||||
GType fpi_tod_shared_driver_get_type (void);
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* FpContext Unit tests
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.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
|
||||
*/
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
static void
|
||||
test_context_new (void)
|
||||
{
|
||||
g_autoptr(FpContext) context = fp_context_new ();
|
||||
g_assert_true (FP_CONTEXT (context));
|
||||
}
|
||||
|
||||
static void
|
||||
test_context_has_no_devices (void)
|
||||
{
|
||||
g_autoptr(FpContext) context = NULL;
|
||||
GPtrArray *devices;
|
||||
const char *old_drivers_dir = g_getenv ("FP_TOD_DRIVERS_DIR");
|
||||
|
||||
g_setenv ("FP_TOD_DRIVERS_DIR", "__HOPEFULLY_AN_INVALID_PATH", TRUE);
|
||||
context = fp_context_new ();
|
||||
devices = fp_context_get_devices (context);
|
||||
g_setenv ("FP_TOD_DRIVERS_DIR", old_drivers_dir, TRUE);
|
||||
|
||||
g_assert_nonnull (devices);
|
||||
g_assert_cmpuint (devices->len, ==, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_context_has_fake_device (void)
|
||||
{
|
||||
g_autoptr(FpContext) context = NULL;
|
||||
FpDevice *fake_device = NULL;
|
||||
GPtrArray *devices;
|
||||
unsigned int i;
|
||||
|
||||
context = fp_context_new ();
|
||||
devices = fp_context_get_devices (context);
|
||||
|
||||
g_assert_nonnull (devices);
|
||||
g_assert_cmpuint (devices->len, ==, 1);
|
||||
|
||||
for (i = 0; i < devices->len; ++i)
|
||||
{
|
||||
FpDevice *device = devices->pdata[i];
|
||||
|
||||
if (g_strcmp0 (fp_device_get_driver (device), "fake_test_dev") == 0)
|
||||
{
|
||||
fake_device = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_true (FP_IS_DEVICE (fake_device));
|
||||
}
|
||||
|
||||
static void
|
||||
test_context_enumerates_new_devices (void)
|
||||
{
|
||||
g_autoptr(FpContext) context = NULL;
|
||||
GPtrArray *devices;
|
||||
|
||||
context = fp_context_new ();
|
||||
|
||||
fp_context_enumerate (context);
|
||||
devices = fp_context_get_devices (context);
|
||||
|
||||
g_assert_nonnull (devices);
|
||||
g_assert_cmpuint (devices->len, ==, 1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_assert_nonnull (g_getenv ("FP_TOD_DRIVERS_DIR"));
|
||||
|
||||
g_test_add_func ("/context/new", test_context_new);
|
||||
g_test_add_func ("/context/no-devices", test_context_has_no_devices);
|
||||
g_test_add_func ("/context/has-virtual-device", test_context_has_fake_device);
|
||||
g_test_add_func ("/context/enumerates-new-devices", test_context_enumerates_new_devices);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* FpDevice Unit tests
|
||||
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.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
|
||||
*/
|
||||
|
||||
#include <libfprint/fprint.h>
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
static FptContext *
|
||||
fpt_context_new_with_fake_dev (void)
|
||||
{
|
||||
FptContext *tctx;
|
||||
GPtrArray *devices;
|
||||
unsigned int i;
|
||||
|
||||
tctx = fpt_context_new ();
|
||||
devices = fp_context_get_devices (tctx->fp_context);
|
||||
|
||||
g_assert_nonnull (devices);
|
||||
g_assert_cmpuint (devices->len, ==, 1);
|
||||
|
||||
for (i = 0; i < devices->len; ++i)
|
||||
{
|
||||
FpDevice *device = devices->pdata[i];
|
||||
|
||||
if (g_strcmp0 (fp_device_get_driver (device), "fake_test_dev") == 0)
|
||||
{
|
||||
tctx->device = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert_true (FP_IS_DEVICE (tctx->device));
|
||||
g_object_add_weak_pointer (G_OBJECT (tctx->device), (gpointer) & tctx->device);
|
||||
|
||||
return tctx;
|
||||
}
|
||||
|
||||
static void
|
||||
on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_assert_true (fp_device_open_finish (dev, res, &error));
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (fp_device_is_open (tctx->device));
|
||||
|
||||
tctx->user_data = GUINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_open_async (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||
|
||||
while (!GPOINTER_TO_UINT (tctx->user_data))
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_device_closed (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_assert_true (fp_device_close_finish (dev, res, &error));
|
||||
g_assert_no_error (error);
|
||||
g_assert_false (fp_device_is_open (tctx->device));
|
||||
|
||||
tctx->user_data = GUINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_close_async (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
|
||||
while (!tctx->user_data)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
tctx->user_data = GUINT_TO_POINTER (FALSE);
|
||||
fp_device_close (tctx->device, NULL, (GAsyncReadyCallback) on_device_closed, tctx);
|
||||
|
||||
while (!GPOINTER_TO_UINT (tctx->user_data))
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_open_sync (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (fp_device_is_open (tctx->device));
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, &error);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_ALREADY_OPEN);
|
||||
}
|
||||
|
||||
static void
|
||||
on_open_notify (FpDevice *rdev, GParamSpec *spec, FptContext *tctx)
|
||||
{
|
||||
g_assert_cmpstr (spec->name, ==, "open");
|
||||
tctx->user_data = GUINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_open_sync_notify (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
|
||||
fp_device_open_sync (tctx->device, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (GPOINTER_TO_INT (tctx->user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_close_sync (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
fp_device_close_sync (tctx->device, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_false (fp_device_is_open (tctx->device));
|
||||
|
||||
fp_device_close_sync (tctx->device, NULL, &error);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_OPEN);
|
||||
}
|
||||
|
||||
static void
|
||||
on_close_notify (FpDevice *rdev, GParamSpec *spec, FptContext *tctx)
|
||||
{
|
||||
g_assert_cmpstr (spec->name, ==, "open");
|
||||
tctx->user_data = GUINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_close_sync_notify (void)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
|
||||
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_close_notify), tctx);
|
||||
fp_device_close_sync (tctx->device, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (GPOINTER_TO_INT (tctx->user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_get_driver (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "fake_test_dev");
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_get_device_id (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "fake_test_dev");
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_get_name (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
|
||||
"Virtual device for debugging");
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_get_scan_type (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_PRESS);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_get_nr_enroll_stages (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_supports_identify (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_true (fp_device_supports_identify (tctx->device));
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_supports_capture (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_true (fp_device_supports_capture (tctx->device));
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_has_storage (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev ();
|
||||
|
||||
fp_device_open_sync (tctx->device, NULL, NULL);
|
||||
g_assert_true (fp_device_has_storage (tctx->device));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_assert_nonnull (g_getenv ("FP_TOD_DRIVERS_DIR"));
|
||||
|
||||
g_test_add_func ("/device/async/open", test_device_open_async);
|
||||
g_test_add_func ("/device/async/close", test_device_close_async);
|
||||
g_test_add_func ("/device/sync/open", test_device_open_sync);
|
||||
g_test_add_func ("/device/sync/open/notify", test_device_open_sync_notify);
|
||||
g_test_add_func ("/device/sync/close", test_device_close_sync);
|
||||
g_test_add_func ("/device/sync/close/notify", test_device_close_sync_notify);
|
||||
g_test_add_func ("/device/sync/get_driver", test_device_get_driver);
|
||||
g_test_add_func ("/device/sync/get_device_id", test_device_get_device_id);
|
||||
g_test_add_func ("/device/sync/get_name", test_device_get_name);
|
||||
g_test_add_func ("/device/sync/get_scan_type", test_device_get_scan_type);
|
||||
g_test_add_func ("/device/sync/get_nr_enroll_stages", test_device_get_nr_enroll_stages);
|
||||
g_test_add_func ("/device/sync/supports_identify", test_device_supports_identify);
|
||||
g_test_add_func ("/device/sync/supports_capture", test_device_supports_capture);
|
||||
g_test_add_func ("/device/sync/has_storage", test_device_has_storage);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
Reference in New Issue
Block a user