diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 589e86c0..3635d4a0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,16 @@ include: file: '/templates/fedora.yml' - remote: 'https://gitlab.gnome.org/GNOME/citemplates/-/raw/master/flatpak/flatpak_ci_initiative.yml' +default: + # Auto-retry jobs in case of infra failures + retry: + max: 1 + when: + - 'runner_system_failure' + - 'stuck_or_timeout_failure' + - 'scheduler_failure' + - 'api_failure' + variables: extends: .libfprint_common_variables FDO_DISTRIBUTION_TAG: $LIBFPRINT_IMAGE_TAG @@ -15,6 +25,11 @@ variables: BUNDLE: "org.freedesktop.libfprint.Demo.flatpak" LAST_ABI_BREAK: "056ea541ddc97f5806cffbd99a12dc87e4da3546" +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' + stages: - image-build - check-source @@ -27,16 +42,16 @@ 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 + - meson setup _build --werror -Ddrivers=$driver + - meson compile -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 + - meson setup _build --werror -Ddrivers=all + - meson compile -C _build + - meson install -C _build .build_template: &check_abi script: @@ -65,11 +80,10 @@ test: variables: - $CI_PIPELINE_SOURCE == "schedule" script: - - meson --werror -Ddrivers=all -Db_coverage=true . _build - - ninja -C _build + - meson setup _build --werror -Ddrivers=all -Db_coverage=true - meson test -C _build --print-errorlogs --no-stdsplit --timeout-multiplier 3 - ninja -C _build coverage - - cat _build/meson-logs/coverage.txt + - cat _build/meson-logs/coverage.txt || true artifacts: reports: junit: "_build/meson-logs/testlog.junit.xml" @@ -91,12 +105,12 @@ test_valgrind: variables: - $CI_PIPELINE_SOURCE == "schedule" script: - - meson -Ddrivers=all . _build - - ninja -C _build + - meson setup _build -Ddrivers=all + - meson compile -C _build - meson test -C _build --print-errorlogs --no-stdsplit --setup=valgrind artifacts: reports: - junit: "_build/meson-logs/testlog.junit.xml" + junit: "_build/meson-logs/testlog-valgrind.junit.xml" expose_as: 'Valgrind test logs' when: always paths: @@ -104,6 +118,27 @@ test_valgrind: - _build/meson-logs/testlog-valgrind.txt expire_in: 1 week +test_installed: + stage: test + except: + variables: + - $CI_PIPELINE_SOURCE == "schedule" + script: + - meson setup _build --prefix=/usr -Ddrivers=all + - meson install -C _build + - gnome-desktop-testing-runner --list libfprint-2 + - gnome-desktop-testing-runner libfprint-2 + --report-directory=_build/installed-tests-report/failed/ + --log-directory=_build/installed-tests-report/logs/ + --parallel=0 + artifacts: + expose_as: 'GNOME Tests Runner logs' + when: always + paths: + - _build/meson-logs + - _build/installed-tests-report + expire_in: 1 week + test_scan_build: stage: test @@ -112,9 +147,10 @@ test_scan_build: - $CI_PIPELINE_SOURCE == "schedule" allow_failure: true script: - - meson -Ddrivers=all . _build + - meson setup _build -Ddrivers=all # Wrapper to add --status-bugs and disable malloc checker - - SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build ninja -C _build scan-build + - SCANBUILD=$CI_PROJECT_DIR/.gitlab-ci/scan-build + ninja -C _build scan-build artifacts: paths: - _build/meson-logs @@ -172,7 +208,6 @@ flatpak: - $CI_PIPELINE_SOURCE == "never" variables: GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image - FDO_FORCE_REBUILD: 1 # a list of packages to install FDO_DISTRIBUTION_PACKAGES: $LIBFPRINT_DEPENDENCIES @@ -182,14 +217,22 @@ flatpak: FDO_DISTRIBUTION_EXEC: | $LIBFPRINT_EXEC +.container_fedora_build_forced: + variables: + FDO_FORCE_REBUILD: 1 + container_fedora_build_schedule: - extends: .container_fedora_build_base + extends: + - .container_fedora_build_base + - .container_fedora_build_forced only: variables: - $CI_PIPELINE_SOURCE == "schedule" && $CRON_TASK == "BUILD_CI_IMAGES" container_fedora_build_manual: - extends: .container_fedora_build_base + extends: + - .container_fedora_build_base + - .container_fedora_build_forced only: variables: - $LIBFPRINT_CI_ACTION == "build-image" diff --git a/.gitlab-ci/libfprint-image-variables.yaml b/.gitlab-ci/libfprint-image-variables.yaml index 5244a2bd..e568839b 100644 --- a/.gitlab-ci/libfprint-image-variables.yaml +++ b/.gitlab-ci/libfprint-image-variables.yaml @@ -1,2 +1,2 @@ variables: - LIBFPRINT_IMAGE_TAG: v2 + LIBFPRINT_IMAGE_TAG: v3 diff --git a/.gitlab-ci/libfprint-templates.yaml b/.gitlab-ci/libfprint-templates.yaml index dc35f806..9c8de1ca 100644 --- a/.gitlab-ci/libfprint-templates.yaml +++ b/.gitlab-ci/libfprint-templates.yaml @@ -13,6 +13,7 @@ glib2-devel glibc-devel gobject-introspection-devel + gnome-desktop-testing gtk-doc gtk3-devel libabigail @@ -33,7 +34,8 @@ diffutils LIBFPRINT_EXEC: | - dnf debuginfo-install -y \ + dnf -y install dnf-utils + debuginfo-install -y \ glib2 \ glibc \ libgusb \ diff --git a/NEWS b/NEWS index 95c8b2a1..1b87665e 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,21 @@ This file lists notable changes in each release. For the full history of all changes, see ChangeLog. +2023-08-17: v1.94.6 release + +Highlights: + * goodixmoc: New PIDs 0x60A4, 0x60BC, 0x6092, 0x633C and 0x6304. + * goodixmoc: Fix missing "enroll create" state. + * elanmoc: New PID 0x0C99. + * upektc: Improve compatibility with sensors 147e:2016. + * aes4000: Actually support 08FF:5501 devices. + * virtual-device-listener: Fix failing tests with GLib 2.76 + * tests: Add installed tests + +Bugs fixed: + * #526 libfprint: fpcmoc: use after free if enrollment or identification is + cancelled (Vasily Khoruzhick) + 2022-10-13: v1.94.5 release Highlights: diff --git a/data/autosuspend.hwdb b/data/autosuspend.hwdb index d476f7e1..603c5c1f 100644 --- a/data/autosuspend.hwdb +++ b/data/autosuspend.hwdb @@ -67,7 +67,7 @@ usb:v08FFp5731* ID_PERSIST=0 # Supported by libfprint driver aes4000 -usb:v5501p08FF* +usb:v08FFp5501* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -149,6 +149,7 @@ usb:v04F3p0C82* usb:v04F3p0C88* usb:v04F3p0C8C* usb:v04F3p0C8D* +usb:v04F3p0C99* ID_AUTOSUSPEND=1 ID_PERSIST=0 @@ -169,10 +170,15 @@ usb:v10A5pD205* # Supported by libfprint driver goodixmoc usb:v27C6p5840* usb:v27C6p6014* +usb:v27C6p6092* usb:v27C6p6094* usb:v27C6p609C* usb:v27C6p60A2* +usb:v27C6p60A4* +usb:v27C6p60BC* +usb:v27C6p6304* usb:v27C6p631C* +usb:v27C6p633C* usb:v27C6p634C* usb:v27C6p6384* usb:v27C6p639C* diff --git a/demo/gtk-libfprint-test.c b/demo/gtk-libfprint-test.c index 68500639..30e91ef2 100644 --- a/demo/gtk-libfprint-test.c +++ b/demo/gtk-libfprint-test.c @@ -102,9 +102,9 @@ plot_minutiae (unsigned char *rgbdata, int i; #define write_pixel(num) do { \ - rgbdata[((num) * 3)] = 0xff; \ - rgbdata[((num) * 3) + 1] = 0; \ - rgbdata[((num) * 3) + 2] = 0; \ + rgbdata[((num) * 3)] = 0xff; \ + rgbdata[((num) * 3) + 1] = 0; \ + rgbdata[((num) * 3) + 2] = 0; \ } while(0) for (i = 0; i < minutiae->len; i++) diff --git a/doc/meson.build b/doc/meson.build index 1a45aad8..77236a06 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -25,7 +25,7 @@ docpath = join_paths(get_option('datadir'), 'gtk-doc', 'html') gnome.gtkdoc(versioned_libname, main_xml: 'libfprint-docs.xml', - src_dir: join_paths(meson.source_root(), 'libfprint'), + src_dir: join_paths(meson.project_source_root(), 'libfprint'), include_directories: include_directories('../libfprint'), dependencies: libfprint_dep, content_files: content_files, diff --git a/examples/meson.build b/examples/meson.build index 3f213470..c223413a 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -22,6 +22,11 @@ executable('cpp-test', dependencies: libfprint_dep, ) +if installed_tests + install_subdir('prints', + install_dir: installed_tests_testdir) +endif + if get_option('tod') executable('tod-inspector', sources: 'tod-inspector.c', diff --git a/libfprint/drivers/aes4000.c b/libfprint/drivers/aes4000.c index e5770b9e..d810b3e4 100644 --- a/libfprint/drivers/aes4000.c +++ b/libfprint/drivers/aes4000.c @@ -124,7 +124,7 @@ G_DEFINE_TYPE (FpiDeviceAes4000, fpi_device_aes4000, FPI_TYPE_DEVICE_AES3K); static const FpIdEntry id_table[] = { - { .pid = 0x08ff, .vid = 0x5501 }, + { .vid = 0x08ff, .pid = 0x5501 }, { .vid = 0, .pid = 0, .driver_data = 0 }, }; diff --git a/libfprint/drivers/elanmoc/elanmoc.c b/libfprint/drivers/elanmoc/elanmoc.c index 471189fd..0261bfff 100644 --- a/libfprint/drivers/elanmoc/elanmoc.c +++ b/libfprint/drivers/elanmoc/elanmoc.c @@ -31,6 +31,7 @@ static const FpIdEntry id_table[] = { { .vid = 0x04f3, .pid = 0x0c88, }, { .vid = 0x04f3, .pid = 0x0c8c, }, { .vid = 0x04f3, .pid = 0x0c8d, }, + { .vid = 0x04f3, .pid = 0x0c99, }, { .vid = 0, .pid = 0, .driver_data = 0 }, /* terminating entry */ }; @@ -1086,6 +1087,10 @@ elanmoc_open (FpDevice *device) self->max_moc_enroll_time = 11; break; + case 0x0c99: + self->max_moc_enroll_time = 14; + break; + case 0x0c8d: self->max_moc_enroll_time = 17; break; diff --git a/libfprint/drivers/fpcmoc/fpc.c b/libfprint/drivers/fpcmoc/fpc.c index b64cc36e..dd6bf090 100644 --- a/libfprint/drivers/fpcmoc/fpc.c +++ b/libfprint/drivers/fpcmoc/fpc.c @@ -132,7 +132,11 @@ fpc_cmd_receive_cb (FpiUsbTransfer *transfer, } ssm_state = fpi_ssm_get_cur_state (transfer->ssm); - fp_dbg ("%s current ssm state: %d", G_STRFUNC, ssm_state); + fp_dbg ("%s current ssm request: %d state: %d", G_STRFUNC, data->request, ssm_state); + + /* clean cmd_ssm except capture command for suspend/resume case */ + if (ssm_state != FP_CMD_SEND || data->request != FPC_CMD_ARM) + self->cmd_ssm = NULL; if (data->cmdtype == FPC_CMDTYPE_TO_DEVICE) { @@ -358,6 +362,7 @@ fpc_sensor_cmd (FpiDeviceFpcMoc *self, g_clear_object (&self->interrupt_cancellable); } + g_assert (self->cmd_ssm == NULL); self->cmd_ssm = fpi_ssm_new (FP_DEVICE (self), fpc_cmd_run_state, FP_CMD_NUM_STATES); @@ -1149,12 +1154,9 @@ fpc_enroll_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) fp_info ("Enrollment complete!"); - if (fpi_ssm_get_error (ssm)) - error = fpi_ssm_get_error (ssm); - if (error) { - fpi_device_enroll_complete (dev, NULL, error); + fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error)); self->task_ssm = NULL; return; } @@ -1336,9 +1338,6 @@ fpc_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) fp_info ("Verify_identify complete!"); - if (fpi_ssm_get_error (ssm)) - error = fpi_ssm_get_error (ssm); - if (error && error->domain == FP_DEVICE_RETRY) { if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY) @@ -1348,9 +1347,9 @@ fpc_verify_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) } if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_VERIFY) - fpi_device_verify_complete (dev, error); + fpi_device_verify_complete (dev, g_steal_pointer (&error)); else - fpi_device_identify_complete (dev, error); + fpi_device_identify_complete (dev, g_steal_pointer (&error)); self->task_ssm = NULL; } @@ -1448,10 +1447,7 @@ fpc_clear_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) fp_info ("Clear Storage complete!"); - if (fpi_ssm_get_error (ssm)) - error = fpi_ssm_get_error (ssm); - - fpi_device_clear_storage_complete (dev, error); + fpi_device_clear_storage_complete (dev, g_steal_pointer (&error)); self->task_ssm = NULL; } @@ -1555,10 +1551,7 @@ fpc_init_ssm_done (FpiSsm *ssm, FpDevice *dev, GError *error) { FpiDeviceFpcMoc *self = FPI_DEVICE_FPCMOC (dev); - if (fpi_ssm_get_error (ssm)) - error = fpi_ssm_get_error (ssm); - - fpi_device_open_complete (dev, error); + fpi_device_open_complete (dev, g_steal_pointer (&error)); self->task_ssm = NULL; } diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index 48dafe10..bacb4845 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -631,20 +631,20 @@ fp_enroll_enum_cb (FpiDeviceGoodixMoc *self, return; } - fpi_ssm_jump_to_state (self->task_ssm, FP_ENROLL_CAPTURE); + fpi_ssm_next_state (self->task_ssm); } static void -fp_enroll_init_cb (FpiDeviceGoodixMoc *self, - gxfp_cmd_response_t *resp, - GError *error) +fp_enroll_create_cb (FpiDeviceGoodixMoc *self, + gxfp_cmd_response_t *resp, + GError *error) { if (error) { fpi_ssm_mark_failed (self->task_ssm, error); return; } - memcpy (self->template_id, resp->enroll_init.tid, TEMPLATE_ID_SIZE); + memcpy (self->template_id, resp->enroll_create.tid, TEMPLATE_ID_SIZE); fpi_ssm_next_state (self->task_ssm); } @@ -837,16 +837,6 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device) switch (fpi_ssm_get_cur_state (ssm)) { - case FP_ENROLL_ENUM: - { - goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT, - false, - (const guint8 *) &dummy, - 1, - fp_enroll_enum_cb); - } - break; - case FP_ENROLL_PWR_BTN_SHIELD_ON: { goodix_sensor_cmd (self, MOC_CMD0_PWR_BTN_SHIELD, MOC_CMD1_PWR_BTN_SHIELD_ON, @@ -857,13 +847,23 @@ fp_enroll_sm_run_state (FpiSsm *ssm, FpDevice *device) } break; + case FP_ENROLL_ENUM: + { + goodix_sensor_cmd (self, MOC_CMD0_GETFINGERLIST, MOC_CMD1_DEFAULT, + false, + (const guint8 *) &dummy, + 1, + fp_enroll_enum_cb); + } + break; + case FP_ENROLL_CREATE: { goodix_sensor_cmd (self, MOC_CMD0_ENROLL_INIT, MOC_CMD1_DEFAULT, false, (const guint8 *) &dummy, 1, - fp_enroll_init_cb); + fp_enroll_create_cb); } break; @@ -1359,10 +1359,15 @@ gx_fp_probe (FpDevice *device) { case 0x6496: case 0x60A2: + case 0x60A4: case 0x6014: + case 0x6092: case 0x6094: case 0x609C: + case 0x60BC: + case 0x6304: case 0x631C: + case 0x633C: case 0x634C: case 0x6384: case 0x639C: @@ -1602,10 +1607,15 @@ fpi_device_goodixmoc_init (FpiDeviceGoodixMoc *self) static const FpIdEntry id_table[] = { { .vid = 0x27c6, .pid = 0x5840, }, { .vid = 0x27c6, .pid = 0x6014, }, + { .vid = 0x27c6, .pid = 0x6092, }, { .vid = 0x27c6, .pid = 0x6094, }, { .vid = 0x27c6, .pid = 0x609C, }, { .vid = 0x27c6, .pid = 0x60A2, }, + { .vid = 0x27c6, .pid = 0x60A4, }, + { .vid = 0x27c6, .pid = 0x60BC, }, + { .vid = 0x27c6, .pid = 0x6304, }, { .vid = 0x27c6, .pid = 0x631C, }, + { .vid = 0x27c6, .pid = 0x633C, }, { .vid = 0x27c6, .pid = 0x634C, }, { .vid = 0x27c6, .pid = 0x6384, }, { .vid = 0x27c6, .pid = 0x639C, }, diff --git a/libfprint/drivers/goodixmoc/goodix.h b/libfprint/drivers/goodixmoc/goodix.h index 56b2d171..4ec5511f 100644 --- a/libfprint/drivers/goodixmoc/goodix.h +++ b/libfprint/drivers/goodixmoc/goodix.h @@ -44,7 +44,6 @@ typedef enum { typedef enum { FP_ENROLL_PWR_BTN_SHIELD_ON = 0, FP_ENROLL_ENUM, - FP_ENROLL_IDENTIFY, FP_ENROLL_CREATE, FP_ENROLL_CAPTURE, FP_ENROLL_UPDATE, diff --git a/libfprint/drivers/goodixmoc/goodix_proto.c b/libfprint/drivers/goodixmoc/goodix_proto.c index 72511a88..d7713f0b 100644 --- a/libfprint/drivers/goodixmoc/goodix_proto.c +++ b/libfprint/drivers/goodixmoc/goodix_proto.c @@ -343,10 +343,10 @@ gx_proto_parse_body (uint16_t cmd, uint8_t *buffer, uint16_t buffer_len, pgxfp_c break; case MOC_CMD0_ENROLL_INIT: - if (buffer_len < sizeof (gxfp_enroll_init_t) + 1) + if (buffer_len < sizeof (gxfp_enroll_create_t) + 1) return -1; if (presp->result == GX_SUCCESS) - memcpy (&presp->enroll_init.tid, &buffer[1], TEMPLATE_ID_SIZE); + memcpy (&presp->enroll_create.tid, &buffer[1], TEMPLATE_ID_SIZE); break; case MOC_CMD0_ENROLL: @@ -465,4 +465,4 @@ gx_proto_init_sensor_config (pgxfp_sensor_cfg_t pconfig) memcpy (pconfig->crc_value, &crc32_calc, PACKAGE_CRC_SIZE); return 0; -} \ No newline at end of file +} diff --git a/libfprint/drivers/goodixmoc/goodix_proto.h b/libfprint/drivers/goodixmoc/goodix_proto.h index 000be2fe..b8ccdca8 100644 --- a/libfprint/drivers/goodixmoc/goodix_proto.h +++ b/libfprint/drivers/goodixmoc/goodix_proto.h @@ -105,10 +105,10 @@ typedef struct _gxfp_parse_msg } gxfp_parse_msg_t, *pgxfp_parse_msg_t; -typedef struct _gxfp_enroll_init +typedef struct _gxfp_enroll_create { uint8_t tid[TEMPLATE_ID_SIZE]; -} gxfp_enroll_init_t, *pgxfp_enroll_init_t; +} gxfp_enroll_create_t, *pgxfp_enroll_create_t; #pragma pack(push, 1) typedef struct _template_format @@ -192,7 +192,7 @@ typedef struct _fp_cmd_response { gxfp_parse_msg_t parse_msg; gxfp_verify_t verify; - gxfp_enroll_init_t enroll_init; + gxfp_enroll_create_t enroll_create; gxfp_capturedata_t capture_data_resp; gxfp_check_duplicate_t check_duplicate_resp; gxfp_enroll_commit_t enroll_commit; diff --git a/libfprint/drivers/upeksonly.c b/libfprint/drivers/upeksonly.c index 9d93cc76..e7ea3ce2 100644 --- a/libfprint/drivers/upeksonly.c +++ b/libfprint/drivers/upeksonly.c @@ -74,26 +74,26 @@ struct _FpiDeviceUpeksonly FpiSsm *loopsm; /* Do we really need multiple concurrent transfers? */ - GCancellable *img_cancellable; - GPtrArray *img_transfers; - int num_flying; + GCancellable *img_cancellable; + GPtrArray *img_transfers; + int num_flying; - GSList *rows; - unsigned num_rows; - unsigned char *rowbuf; - int rowbuf_offset; + GSList *rows; + unsigned num_rows; + unsigned char *rowbuf; + int rowbuf_offset; - int wraparounds; - int num_blank; - int num_nonblank; - enum sonly_fs finger_state; - int last_seqnum; + int wraparounds; + int num_blank; + int num_nonblank; + enum sonly_fs finger_state; + int last_seqnum; enum sonly_kill_transfers_action killing_transfers; - GError *kill_error; - FpiSsm *kill_ssm; + GError *kill_error; + FpiSsm *kill_ssm; - struct fpi_line_asmbl_ctx assembling_ctx; + struct fpi_line_asmbl_ctx assembling_ctx; }; G_DECLARE_FINAL_TYPE (FpiDeviceUpeksonly, fpi_device_upeksonly, FPI, DEVICE_UPEKSONLY, FpImageDevice); diff --git a/libfprint/drivers/upektc_img.c b/libfprint/drivers/upektc_img.c index 19bc4158..f2c6edb8 100644 --- a/libfprint/drivers/upektc_img.c +++ b/libfprint/drivers/upektc_img.c @@ -31,10 +31,6 @@ static void start_deactivation (FpImageDevice *dev); #define CTRL_TIMEOUT 4000 #define BULK_TIMEOUT 4000 -#define IMAGE_WIDTH 144 -#define IMAGE_HEIGHT 384 -#define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT) - #define MAX_CMD_SIZE 64 #define MAX_RESPONSE_SIZE 2052 #define SHORT_RESPONSE_SIZE 64 @@ -47,8 +43,10 @@ struct _FpiDeviceUpektcImg unsigned char response[MAX_RESPONSE_SIZE]; unsigned char *image_bits; unsigned char seq; + size_t expected_image_size; size_t image_size; size_t response_rest; + gboolean area_sensor; gboolean deactivating; }; G_DECLARE_FINAL_TYPE (FpiDeviceUpektcImg, fpi_device_upektc_img, FPI, @@ -180,6 +178,7 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, gpointer user_data, GError *error) { FpImageDevice *dev = FP_IMAGE_DEVICE (device); + FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_GET_CLASS (dev); FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev); unsigned char *data = self->response; FpImage *img; @@ -247,8 +246,30 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, CAPTURE_ACK_00_28); break; + case 0x13: + /* finger is present keep your finger on reader */ + fpi_device_report_finger_status_changes (device, + FP_FINGER_STATUS_NEEDED, + FP_FINGER_STATUS_NONE); + fpi_ssm_jump_to_state (transfer->ssm, + self->area_sensor ? + CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM); + break; + case 0x00: /* finger is present! */ + fpi_device_report_finger_status_changes (device, + FP_FINGER_STATUS_PRESENT, + FP_FINGER_STATUS_NONE); + fpi_ssm_jump_to_state (transfer->ssm, + CAPTURE_ACK_00_28); + break; + + case 0x01: + /* no finger! */ + fpi_device_report_finger_status_changes (device, + FP_FINGER_STATUS_NONE, + FP_FINGER_STATUS_PRESENT); fpi_ssm_jump_to_state (transfer->ssm, CAPTURE_ACK_00_28); break; @@ -261,18 +282,20 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, fpi_image_device_report_finger_status (dev, FALSE); fpi_ssm_jump_to_state (transfer->ssm, - CAPTURE_ACK_00_28_TERM); + self->area_sensor ? + CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM); break; case 0x1d: - /* too much horisontal movement */ - fp_err ("too much horisontal movement, aborting"); + /* too much horizontal movement */ + fp_err ("too much horizontal movement, aborting"); fpi_image_device_retry_scan (dev, FP_DEVICE_RETRY_CENTER_FINGER); fpi_image_device_report_finger_status (dev, FALSE); fpi_ssm_jump_to_state (transfer->ssm, - CAPTURE_ACK_00_28_TERM); + self->area_sensor ? + CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM); break; default: @@ -283,7 +306,8 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, fpi_image_device_report_finger_status (dev, FALSE); fpi_ssm_jump_to_state (transfer->ssm, - CAPTURE_ACK_00_28_TERM); + self->area_sensor ? + CAPTURE_ACK_00_28 : CAPTURE_ACK_00_28_TERM); break; } break; @@ -307,13 +331,13 @@ capture_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, self->image_size += upektc_img_process_image_frame (self->image_bits + self->image_size, data); - BUG_ON (self->image_size != IMAGE_SIZE); + BUG_ON (self->image_size != self->expected_image_size); fp_dbg ("Image size is %lu", (gulong) self->image_size); - img = fp_image_new (IMAGE_WIDTH, IMAGE_HEIGHT); + img = fp_image_new (img_class->img_width, img_class->img_height); img->flags |= FPI_IMAGE_PARTIAL; memcpy (img->data, self->image_bits, - IMAGE_SIZE); + self->image_size); fpi_image_device_image_captured (dev, img); fpi_image_device_report_finger_status (dev, FALSE); @@ -346,8 +370,12 @@ capture_run_state (FpiSsm *ssm, FpDevice *_dev) switch (fpi_ssm_get_cur_state (ssm)) { case CAPTURE_INIT_CAPTURE: - upektc_img_submit_req (ssm, dev, upek2020_init_capture, sizeof (upek2020_init_capture), - self->seq, capture_reqs_cb); + if (self->area_sensor) + upektc_img_submit_req (ssm, dev, upek2020_init_capture_press, sizeof (upek2020_init_capture_press), + self->seq, capture_reqs_cb); + else + upektc_img_submit_req (ssm, dev, upek2020_init_capture, sizeof (upek2020_init_capture), + self->seq, capture_reqs_cb); self->seq++; break; @@ -513,15 +541,81 @@ init_reqs_cb (FpiUsbTransfer *transfer, FpDevice *device, fpi_ssm_mark_failed (transfer->ssm, error); } -/* TODO: process response properly */ static void init_read_data_cb (FpiUsbTransfer *transfer, FpDevice *device, gpointer user_data, GError *error) { - if (!error) - fpi_ssm_next_state (transfer->ssm); - else - fpi_ssm_mark_failed (transfer->ssm, error); + FpImageDevice *dev = FP_IMAGE_DEVICE (device); + FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev); + unsigned char *data = self->response; + + if (error) + { + fpi_ssm_mark_failed (transfer->ssm, error); + return; + } + + if (data[12] == 0x06 && data[13] == 0x14) /* if get_info */ + { + FpImageDeviceClass *img_class = FP_IMAGE_DEVICE_GET_CLASS (dev); + uint16_t width = (data[51] << 8) | data[50]; + uint16_t height = (data[53] << 8) | data[52]; + + self->area_sensor = !(data[49] & 0x80); + + switch (width) + { + case 256: + fp_dbg ("Sensor type : TCS1x, width x height: %hu x %hu", width, height); /* 360x256 --- 270x192 must be set */ + BUG_ON (height != 360); + img_class->img_width = 192; + img_class->img_height = 270; + break; + + case 208: + fp_dbg ("Sensor type : TCS2, width x height: %hu x %hu", width, height); /* 288x208 --- 216x156 must be set */ + BUG_ON (height != 288); + img_class->img_width = 156; + img_class->img_height = 216; + break; + + case 248: + fp_dbg ("Sensor type : TCS3, width x height: %hu x %hu", width, height); /* 360x248 --- 270x186 must be set */ + BUG_ON (height != 360); + img_class->img_width = 186; + img_class->img_height = 270; + break; + + case 192: + fp_dbg ("Sensor type : TCS4x, width x height: %hu x %hu", width, height); /* 512x192 --- 384x144 must be set */ + BUG_ON (height != 512); + img_class->img_width = 144; + img_class->img_height = 384; + break; + + case 144: + fp_dbg ("Sensor type : TCS5x, width x height: %hu x %hu", width, height); /* 512x144 --- 384x108 must be set */ + BUG_ON (height != 512); + img_class->img_width = 108; + img_class->img_height = 384; + break; + + default: + fp_dbg ("Sensor type : Unknown"); + + fpi_ssm_mark_failed (transfer->ssm, + fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO, + "Unknown sensor type (reported size %dx%d)", + width, height)); + + return; + } + + self->expected_image_size = img_class->img_width * img_class->img_height; + self->image_bits = g_malloc0 (self->expected_image_size * 2); + } + + fpi_ssm_next_state (transfer->ssm); } static void @@ -616,7 +710,6 @@ dev_deactivate (FpImageDevice *dev) static void dev_init (FpImageDevice *dev) { - FpiDeviceUpektcImg *self = FPI_DEVICE_UPEKTC_IMG (dev); GError *error = NULL; /* TODO check that device has endpoints we're using */ @@ -627,7 +720,6 @@ dev_init (FpImageDevice *dev) return; } - self->image_bits = g_malloc0 (IMAGE_SIZE * 2); fpi_image_device_open_complete (dev, NULL); } @@ -687,6 +779,6 @@ fpi_device_upektc_img_class_init (FpiDeviceUpektcImgClass *klass) img_class->bz3_threshold = 20; - img_class->img_width = IMAGE_WIDTH; - img_class->img_height = IMAGE_HEIGHT; + img_class->img_width = -1; + img_class->img_height = -1; } diff --git a/libfprint/drivers/upektc_img.h b/libfprint/drivers/upektc_img.h index 3052b652..1c3a6949 100644 --- a/libfprint/drivers/upektc_img.h +++ b/libfprint/drivers/upektc_img.h @@ -75,6 +75,22 @@ static const unsigned char upek2020_init_capture[] = { 0x02, 0x00, /* Wait for acceptable finger */ 0x02, + 0x25, 0xa9 /* CRC */ +}; + +static const unsigned char upek2020_init_capture_press[] = { + 'C', 'i', 'a', 'o', + 0x00, + 0x00, 0x0e, /* Seq = 7, len = 0x00e */ + 0x28, /* CMD = 0x28 */ + 0x0b, 0x00, /* Inner len = 0x000b */ + 0x00, 0x00, + 0x0e, /* SUBCMD = 0x0e */ + 0x02, + 0xfe, 0xff, 0xff, 0xff, /* timeout = -2 = 0xfffffffe = infinite time */ + 0x02, + 0x01, /* Wait for finger */ + 0x02, 0x14, 0x9a /* CRC */ }; diff --git a/libfprint/drivers/vfs101.c b/libfprint/drivers/vfs101.c index 7020726a..6963c59e 100644 --- a/libfprint/drivers/vfs101.c +++ b/libfprint/drivers/vfs101.c @@ -162,9 +162,9 @@ enum { /* Dump buffer for debug */ #define dump_buffer(buf) \ - fp_dbg ("%02x %02x %02x %02x %02x %02x %02x %02x", \ - buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13] \ - ) + fp_dbg ("%02x %02x %02x %02x %02x %02x %02x %02x", \ + buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13] \ + ) /* Callback of asynchronous send */ static void diff --git a/libfprint/drivers/vfs301_proto.c b/libfprint/drivers/vfs301_proto.c index 122a889a..6bbb3c7d 100644 --- a/libfprint/drivers/vfs301_proto.c +++ b/libfprint/drivers/vfs301_proto.c @@ -157,7 +157,7 @@ vfs301_proto_generate_0B (int subtype, gssize *len) } #define HEX_TO_INT(c) \ - (((c) >= '0' && (c) <= '9') ? ((c) - '0') : ((c) - 'A' + 10)) + (((c) >= '0' && (c) <= '9') ? ((c) - '0') : ((c) - 'A' + 10)) static guint8 * translate_str (const char **srcL, gssize *len) @@ -422,15 +422,15 @@ img_process_data (int first_block, FpDeviceVfs301 *dev, const guint8 *buf, int l /************************** PROTOCOL STUFF ************************************/ #define USB_RECV(from, len) \ - usb_recv (dev, from, len, NULL, NULL) + usb_recv (dev, from, len, NULL, NULL) #define USB_SEND(type, subtype) \ - { \ - const guint8 *data; \ - gssize len; \ - data = vfs301_proto_generate (type, subtype, &len); \ - usb_send (dev, data, len, NULL); \ - } + { \ + const guint8 *data; \ + gssize len; \ + data = vfs301_proto_generate (type, subtype, &len); \ + usb_send (dev, data, len, NULL); \ + } #define RAW_DATA(x) g_memdup2 (x, sizeof (x)), sizeof (x) @@ -489,13 +489,13 @@ vfs301_proto_peek_event (FpDeviceVfs301 *dev) * we will run into timeouts randomly and need to then try again. */ #define PARALLEL_RECEIVE(e1, l1, e2, l2) \ - { \ - g_autoptr(GError) error = NULL; \ - usb_recv (dev, e1, l1, NULL, &error); \ - usb_recv (dev, e2, l2, NULL, NULL); \ - if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \ - usb_recv (dev, e1, l1, NULL, NULL); \ - } + { \ + g_autoptr(GError) error = NULL; \ + usb_recv (dev, e1, l1, NULL, &error); \ + usb_recv (dev, e2, l2, NULL, NULL); \ + if (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT)) \ + usb_recv (dev, e1, l1, NULL, NULL); \ + } static void vfs301_proto_process_event_cb (FpiUsbTransfer *transfer, diff --git a/libfprint/drivers/vfs5011.c b/libfprint/drivers/vfs5011.c index b9e0587b..65c98c96 100644 --- a/libfprint/drivers/vfs5011.c +++ b/libfprint/drivers/vfs5011.c @@ -41,30 +41,30 @@ struct usb_action }; #define SEND(ENDPOINT, COMMAND) \ - { \ - .type = ACTION_SEND, \ - .endpoint = ENDPOINT, \ - .name = #COMMAND, \ - .size = sizeof (COMMAND), \ - .data = COMMAND \ - }, + { \ + .type = ACTION_SEND, \ + .endpoint = ENDPOINT, \ + .name = #COMMAND, \ + .size = sizeof (COMMAND), \ + .data = COMMAND \ + }, #define RECV(ENDPOINT, SIZE) \ - { \ - .type = ACTION_RECEIVE, \ - .endpoint = ENDPOINT, \ - .size = SIZE, \ - .data = NULL \ - }, + { \ + .type = ACTION_RECEIVE, \ + .endpoint = ENDPOINT, \ + .size = SIZE, \ + .data = NULL \ + }, #define RECV_CHECK(ENDPOINT, SIZE, EXPECTED) \ - { \ - .type = ACTION_RECEIVE, \ - .endpoint = ENDPOINT, \ - .size = SIZE, \ - .data = EXPECTED, \ - .correct_reply_size = sizeof (EXPECTED) \ - }, + { \ + .type = ACTION_RECEIVE, \ + .endpoint = ENDPOINT, \ + .size = SIZE, \ + .data = EXPECTED, \ + .correct_reply_size = sizeof (EXPECTED) \ + }, struct usbexchange_data { diff --git a/libfprint/drivers/vfs7552.c b/libfprint/drivers/vfs7552.c index 53b4d3f3..852e35b5 100644 --- a/libfprint/drivers/vfs7552.c +++ b/libfprint/drivers/vfs7552.c @@ -51,39 +51,39 @@ struct usb_action }; #define SEND(ENDPOINT, COMMAND) \ - { \ - .type = ACTION_SEND, \ - .endpoint = ENDPOINT, \ - .name = #COMMAND, \ - .size = sizeof (COMMAND), \ - .data = COMMAND \ - }, + { \ + .type = ACTION_SEND, \ + .endpoint = ENDPOINT, \ + .name = #COMMAND, \ + .size = sizeof (COMMAND), \ + .data = COMMAND \ + }, #define RECV(ENDPOINT, SIZE) \ - { \ - .type = ACTION_RECEIVE, \ - .endpoint = ENDPOINT, \ - .size = SIZE, \ - .data = NULL \ - }, + { \ + .type = ACTION_RECEIVE, \ + .endpoint = ENDPOINT, \ + .size = SIZE, \ + .data = NULL \ + }, #define RECV_CHECK(ENDPOINT, SIZE, EXPECTED) \ - { \ - .type = ACTION_RECEIVE, \ - .endpoint = ENDPOINT, \ - .size = SIZE, \ - .data = EXPECTED, \ - .correct_reply_size = sizeof (EXPECTED) \ - }, + { \ + .type = ACTION_RECEIVE, \ + .endpoint = ENDPOINT, \ + .size = SIZE, \ + .data = EXPECTED, \ + .correct_reply_size = sizeof (EXPECTED) \ + }, #define RECV_CHECK_SIZE(ENDPOINT, SIZE, EXPECTED) \ - { \ - .type = ACTION_RECEIVE, \ - .endpoint = ENDPOINT, \ - .size = SIZE, \ - .data = NULL, \ - .correct_reply_size = sizeof (EXPECTED) \ - }, + { \ + .type = ACTION_RECEIVE, \ + .endpoint = ENDPOINT, \ + .size = SIZE, \ + .data = NULL, \ + .correct_reply_size = sizeof (EXPECTED) \ + }, struct usbexchange_data { diff --git a/libfprint/drivers/virtual-device-listener.c b/libfprint/drivers/virtual-device-listener.c index cd2fe2e0..16987a1b 100644 --- a/libfprint/drivers/virtual-device-listener.c +++ b/libfprint/drivers/virtual-device-listener.c @@ -273,7 +273,8 @@ on_stream_read_cb (GObject *source_object, } else { - // g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Got empty data"); + g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "Got empty data"); return; } } diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c index c75455ff..17a7ad01 100644 --- a/libfprint/drivers/virtual-device.c +++ b/libfprint/drivers/virtual-device.c @@ -733,7 +733,13 @@ dev_deinit (FpDevice *dev) } if (!self->keep_alive) - stop_listener (self); + { + stop_listener (self); + self->supports_cancellation = TRUE; + } + + self->enroll_stages_passed = 0; + self->match_reported = FALSE; fpi_device_close_complete (dev, NULL); } diff --git a/libfprint/fp-print.h b/libfprint/fp-print.h index ac6820d7..7a2abee3 100644 --- a/libfprint/fp-print.h +++ b/libfprint/fp-print.h @@ -29,7 +29,7 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (FpPrint, fp_print, FP, PRINT, GInitiallyUnowned) #define FP_FINGER_IS_VALID(finger) \ - ((finger) >= FP_FINGER_FIRST && (finger) <= FP_FINGER_LAST) + ((finger) >= FP_FINGER_FIRST && (finger) <= FP_FINGER_LAST) #include "fp-device.h" diff --git a/libfprint/fpi-compat.h b/libfprint/fpi-compat.h index 6582fb5a..ad86874a 100644 --- a/libfprint/fpi-compat.h +++ b/libfprint/fpi-compat.h @@ -43,7 +43,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (GDate, g_date_free); #define g_memdup2(data, size) g_memdup ((data), (size)) #else #define g_memdup2(data, size) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ g_memdup2 ((data), (size)); \ G_GNUC_END_IGNORE_DEPRECATIONS \ diff --git a/libfprint/fpi-image.c b/libfprint/fpi-image.c index 95465ad8..98f412a3 100644 --- a/libfprint/fpi-image.c +++ b/libfprint/fpi-image.c @@ -26,7 +26,7 @@ #include #include -#if HAVE_PIXMAN +#ifdef HAVE_PIXMAN #include #endif @@ -113,7 +113,7 @@ fpi_image_resize (FpImage *orig_img, guint w_factor, guint h_factor) { -#if HAVE_PIXMAN +#ifdef HAVE_PIXMAN int new_width = orig_img->width * w_factor; int new_height = orig_img->height * h_factor; pixman_image_t *orig, *resized; @@ -149,6 +149,6 @@ fpi_image_resize (FpImage *orig_img, #else fp_err ("Libfprint compiled without pixman support, impossible to resize"); - return NULL; + return g_object_ref (orig_img); #endif } diff --git a/libfprint/fpi-log.h b/libfprint/fpi-log.h index da612049..3231cf5f 100644 --- a/libfprint/fpi-log.h +++ b/libfprint/fpi-log.h @@ -80,12 +80,12 @@ * Uses fp_err() to print an error if the @condition is true. */ #define BUG_ON(condition) G_STMT_START \ - if (condition) { \ - char *s; \ - s = g_strconcat ("BUG: (", #condition, ")", NULL); \ - fp_err ("%s: %s() %s:%d", s, G_STRFUNC, __FILE__, __LINE__); \ - g_free (s); \ - } G_STMT_END + if (condition) { \ + char *s; \ + s = g_strconcat ("BUG: (", #condition, ")", NULL); \ + fp_err ("%s: %s() %s:%d", s, G_STRFUNC, __FILE__, __LINE__); \ + g_free (s); \ + } G_STMT_END /** * BUG: diff --git a/libfprint/fpi-ssm.h b/libfprint/fpi-ssm.h index d2601c88..ab80a26f 100644 --- a/libfprint/fpi-ssm.h +++ b/libfprint/fpi-ssm.h @@ -60,7 +60,7 @@ typedef void (*FpiSsmHandlerCallback)(FpiSsm *ssm, /* for library and drivers */ #define fpi_ssm_new(dev, handler, nr_states) \ - fpi_ssm_new_full (dev, handler, nr_states, nr_states, #nr_states) + fpi_ssm_new_full (dev, handler, nr_states, nr_states, #nr_states) FpiSsm *fpi_ssm_new_full (FpDevice *dev, FpiSsmHandlerCallback handler, int nr_states, diff --git a/libfprint/fprint-list-supported-devices.c b/libfprint/fprint-list-supported-devices.c index 132a72f0..ace5de09 100644 --- a/libfprint/fprint-list-supported-devices.c +++ b/libfprint/fprint-list-supported-devices.c @@ -132,7 +132,7 @@ main (int argc, char **argv) g_print ("%s", (char *) l->data); g_print ("\n"); - g_list_free_full (usb_list, g_free); + g_list_free_full (g_steal_pointer (&usb_list), g_free); g_print ("## SPI devices\n"); g_print ("\n"); @@ -146,7 +146,7 @@ main (int argc, char **argv) g_print ("%s", (char *) l->data); g_print ("\n"); - g_list_free_full (usb_list, g_free); + g_list_free_full (g_steal_pointer (&spi_list), g_free); g_hash_table_destroy (printed); diff --git a/libfprint/meson.build b/libfprint/meson.build index 856e0b35..0cbccc03 100644 --- a/libfprint/meson.build +++ b/libfprint/meson.build @@ -267,7 +267,7 @@ libfprint_drivers = static_library('fprint-drivers', install: false) mapfile = files('libfprint.ver') -vflag = '-Wl,--version-script,@0@/@1@'.format(meson.source_root(), mapfile[0]) +vflag = '-Wl,--version-script,@0@/@1@'.format(meson.project_source_root(), mapfile[0]) libfprint = shared_library(versioned_libname.split('lib')[1], sources: [ @@ -343,7 +343,7 @@ sync_udev_udb = custom_target('sync-udev-hwdb', command: [ 'cp', '-v', udev_hwdb_generator.full_path(), - meson.source_root() / 'data' + meson.project_source_root() / 'data' ] ) diff --git a/libfprint/tod/tod-macros.h b/libfprint/tod/tod-macros.h index 4adfd941..9c22a58a 100644 --- a/libfprint/tod/tod-macros.h +++ b/libfprint/tod/tod-macros.h @@ -20,13 +20,13 @@ #pragma once #define TOD_PADDING(original, wasted) \ - char _tod_expansion_padding[(GLIB_SIZEOF_VOID_P * (original)) - (wasted)]; + char _tod_expansion_padding[(GLIB_SIZEOF_VOID_P * (original)) - (wasted)]; #define TOD_PADDING_ALIGNED(original, wasted) \ - TOD_PADDING (original, (wasted) + GLIB_SIZEOF_VOID_P) + TOD_PADDING (original, (wasted) + GLIB_SIZEOF_VOID_P) #define TOD_PADDING_ALIGNED4(original, wasted) \ - TOD_PADDING (original, (wasted) + (GLIB_SIZEOF_VOID_P == 4 ? GLIB_SIZEOF_VOID_P : 0)) + TOD_PADDING (original, (wasted) + (GLIB_SIZEOF_VOID_P == 4 ? GLIB_SIZEOF_VOID_P : 0)) #define TOD_PADDING_ALIGNED8(original, wasted) \ - TOD_PADDING (original, (wasted) + (GLIB_SIZEOF_VOID_P == 8 ? GLIB_SIZEOF_VOID_P : 0)) + TOD_PADDING (original, (wasted) + (GLIB_SIZEOF_VOID_P == 8 ? GLIB_SIZEOF_VOID_P : 0)) diff --git a/libfprint/tod/tod-symbols.h b/libfprint/tod/tod-symbols.h index 1f600a2d..de268b91 100644 --- a/libfprint/tod/tod-symbols.h +++ b/libfprint/tod/tod-symbols.h @@ -21,27 +21,27 @@ #define LIBFPRINT_2_SYMBOL_VERSION_2_0 "LIBFPRINT_2.0.0" #define LIBFPRINT_2_SYMBOL_VERSION(major, minor) \ - LIBFPRINT_2_SYMBOL_VERSION_ ## major ## _ ## minor + LIBFPRINT_2_SYMBOL_VERSION_ ## major ## _ ## minor #define TOD_1_SYMBOL_VERSION_1_90 "LIBFPRINT_TOD_1.0.0" #define TOD_1_SYMBOL_VERSION_1_92 "LIBFPRINT_TOD_1_1.92" #define TOD_1_SYMBOL_VERSION_1_94 "LIBFPRINT_TOD_1_1.94" #define TOD_1_SYMBOL_VERSION(major, minor) \ - TOD_1_SYMBOL_VERSION_ ## major ## _ ## minor + TOD_1_SYMBOL_VERSION_ ## major ## _ ## minor #define TOD_DEFAULT_UPSTREAM_SYMBOL_VERSIONED(symbol, major, minor) \ - __asm__ (".symver " # symbol "," # symbol "@@@" \ - LIBFPRINT_2_SYMBOL_VERSION (major, minor)); + __asm__ (".symver " # symbol "," # symbol "@@@" \ + LIBFPRINT_2_SYMBOL_VERSION (major, minor)); #define TOD_DEFAULT_UPSTREAM_SYMBOL(symbol) \ - __asm__ (".symver " # symbol "," # symbol "@@@"); + __asm__ (".symver " # symbol "," # symbol "@@@"); #define TOD_DEFAULT_VERSION_SYMBOL(symbol, major, minor) \ - __asm__ (".symver " # symbol "," # symbol "@@@" \ - TOD_1_SYMBOL_VERSION (major, minor)); + __asm__ (".symver " # symbol "," # symbol "@@@" \ + TOD_1_SYMBOL_VERSION (major, minor)); #define TOD_VERSIONED_SYMBOL(symbol, major, minor) \ - __asm__ (".symver " # symbol "_" # major "_" #minor "," # symbol "@" \ - TOD_1_SYMBOL_VERSION (major, minor)); + __asm__ (".symver " # symbol "_" # major "_" #minor "," # symbol "@" \ + TOD_1_SYMBOL_VERSION (major, minor)); TOD_DEFAULT_VERSION_SYMBOL (fpi_ssm_new_full, 1, 92) TOD_VERSIONED_SYMBOL (fpi_ssm_new_full, 1, 90) diff --git a/meson.build b/meson.build index 188404a0..8a29b90a 100644 --- a/meson.build +++ b/meson.build @@ -1,18 +1,23 @@ project('libfprint', [ 'c', 'cpp' ], - version: '1.94.5+tod1', + version: '1.94.6+tod1', license: 'LGPLv2.1+', default_options: [ 'buildtype=debugoptimized', 'warning_level=1', 'c_std=gnu99', ], - meson_version: '>= 0.49.0') + meson_version: '>= 0.56.0') gnome = import('gnome') libfprint_conf = configuration_data() libfprint_conf.set_quoted('LIBFPRINT_VERSION', meson.project_version()) +prefix = get_option('prefix') +libdir = prefix / get_option('libdir') +libexecdir = prefix / get_option('libexecdir') +datadir = prefix / get_option('datadir') + cc = meson.get_compiler('c') cpp = meson.get_compiler('cpp') host_system = host_machine.system() @@ -286,8 +291,6 @@ else endif if get_option('gtk-examples') - gnome = import('gnome') - gtk_dep = dependency('gtk+-3.0', required: false) if not gtk_dep.found() error('GTK+ 3.x is required for GTK+ examples') @@ -300,9 +303,7 @@ subdir('libfprint') libfprint_conf.set10('HAVE_LIBFPRINT_TOD', get_option('tod')) configure_file(output: 'config.h', configuration: libfprint_conf) -subdir('examples') if get_option('doc') - gnome = import('gnome') subdir('doc') endif if get_option('gtk-examples') @@ -312,6 +313,8 @@ endif subdir('data') subdir('tests') +subdir('examples') + pkgconfig = import('pkgconfig') pkgconfig.generate( name: versioned_libname, @@ -322,3 +325,5 @@ pkgconfig.generate( subdirs: versioned_libname, filebase: versioned_libname, ) + +summary({'Drivers': drivers, }, section: 'Drivers') diff --git a/meson_options.txt b/meson_options.txt index f57beb1a..a925a548 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -31,6 +31,11 @@ option('doc', type: 'boolean', value: true) +option('installed-tests', + description: 'Whether to install the installed tests', + type: 'boolean', + value: true) + option('tod', description: 'Whether to build the TOD library', type: 'boolean', diff --git a/tests/driver.test.in b/tests/driver.test.in new file mode 100644 index 00000000..6416eea6 --- /dev/null +++ b/tests/driver.test.in @@ -0,0 +1,5 @@ +[Test] +Type=session +# We can't use TestEnvironment as per +# https://gitlab.gnome.org/GNOME/gnome-desktop-testing/-/issues/1 +Exec=env @driver_env@ @installed_tests_execdir@/@umockdev_test_name@ @installed_tests_testdir@/@driver_test@ diff --git a/tests/goodixmoc/custom.pcapng b/tests/goodixmoc/custom.pcapng index b5e2d89c..91925244 100644 Binary files a/tests/goodixmoc/custom.pcapng and b/tests/goodixmoc/custom.pcapng differ diff --git a/tests/goodixmoc/device b/tests/goodixmoc/device index 1e209a1d..4f96b612 100644 --- a/tests/goodixmoc/device +++ b/tests/goodixmoc/device @@ -1,31 +1,30 @@ -P: /devices/pci0000:00/0000:00:14.0/usb1/1-3 -N: bus/usb/001/023=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000 -E: DEVNAME=/dev/bus/usb/001/023 +P: /devices/pci0000:00/0000:00:14.0/usb3/3-9 +N: bus/usb/003/004=12010002EF000040C627AC6300010102030109022000010103A0320904000002FF0000040705830240000007050102400000 +E: DEVNAME=/dev/bus/usb/003/004 E: DEVTYPE=usb_device E: DRIVER=usb -E: PRODUCT=27c6/6496/100 +E: PRODUCT=27c6/63ac/100 E: TYPE=239/0/0 -E: BUSNUM=001 -E: DEVNUM=023 +E: BUSNUM=003 +E: DEVNUM=004 E: MAJOR=189 -E: MINOR=22 +E: MINOR=259 E: SUBSYSTEM=usb E: ID_VENDOR=Goodix_Technology_Co.__Ltd. E: ID_VENDOR_ENC=Goodix\x20Technology\x20Co.\x2c\x20Ltd. E: ID_VENDOR_ID=27c6 E: ID_MODEL=Goodix_USB2.0_MISC E: ID_MODEL_ENC=Goodix\x20USB2.0\x20MISC -E: ID_MODEL_ID=6496 +E: ID_MODEL_ID=63ac E: ID_REVISION=0100 -E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_XXXX_MOC_B0 -E: ID_SERIAL_SHORT=XXXX_MOC_B0 +E: ID_SERIAL=Goodix_Technology_Co.__Ltd._Goodix_USB2.0_MISC_UID4C77C784_XXXX_MOC_B0 +E: ID_SERIAL_SHORT=UID4C77C784_XXXX_MOC_B0 E: ID_BUS=usb E: ID_USB_INTERFACES=:ff0000: E: ID_VENDOR_FROM_DATABASE=Shenzhen Goodix Technology Co.,Ltd. E: ID_AUTOSUSPEND=1 -E: ID_PERSIST=0 -E: ID_PATH=pci-0000:00:14.0-usb-0:3 -E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_3 +E: ID_PATH=pci-0000:00:14.0-usb-0:9 +E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9 A: authorized=1\n A: avoid_reset_quirk=0\n A: bConfigurationValue=1\n @@ -38,30 +37,34 @@ A: bNumConfigurations=1\n A: bNumInterfaces= 1\n A: bcdDevice=0100\n A: bmAttributes=a0\n -A: busnum=1\n -A: configuration=XXXX_MOC_B0\n -H: descriptors=12010002EF000040C627966400010102030109022000010103A0320904000002FF0000040705830240000007050102400000 -A: dev=189:22\n -A: devnum=23\n -A: devpath=3\n +A: busnum=3\n +A: configuration=UID4C77C784_XXXX_MOC_B0\n +H: descriptors=12010002EF000040C627AC6300010102030109022000010103A0320904000002FF0000040705830240000007050102400000 +A: dev=189:259\n +A: devnum=4\n +A: devpath=9\n L: driver=../../../../../bus/usb/drivers/usb -L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d/device:20 -A: idProduct=6496\n +L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:13/device:14/device:1f +A: idProduct=63ac\n A: idVendor=27c6\n A: ltm_capable=no\n A: manufacturer=Goodix Technology Co., Ltd.\n A: maxchild=0\n -L: port=../1-0:1.0/usb1-port3 -A: power/active_duration=22667\n +L: port=../3-0:1.0/usb3-port9 +A: power/active_duration=702588\n +A: power/async=enabled\n A: power/autosuspend=2\n A: power/autosuspend_delay_ms=2000\n -A: power/connected_duration=917616\n +A: power/connected_duration=78973756\n A: power/control=auto\n A: power/level=auto\n A: power/persist=1\n -A: power/runtime_active_time=22809\n +A: power/runtime_active_kids=0\n +A: power/runtime_active_time=707156\n +A: power/runtime_enabled=enabled\n A: power/runtime_status=active\n -A: power/runtime_suspended_time=894564\n +A: power/runtime_suspended_time=78265226\n +A: power/runtime_usage=0\n A: power/wakeup=disabled\n A: power/wakeup_abort_count=\n A: power/wakeup_active=\n @@ -73,34 +76,34 @@ A: power/wakeup_max_time_ms=\n A: power/wakeup_total_time_ms=\n A: product=Goodix USB2.0 MISC\n A: quirks=0x0\n -A: removable=removable\n +A: removable=fixed\n A: rx_lanes=1\n -A: serial=XXXX_MOC_B0\n +A: serial=UID4C77C784_XXXX_MOC_B0\n A: speed=12\n A: tx_lanes=1\n -A: urbnum=298\n +A: urbnum=5759\n A: version= 2.00\n -P: /devices/pci0000:00/0000:00:14.0/usb1 -N: bus/usb/001/001=12010002090001406B1D020017050302010109021900010100E0000904000001090000000705810304000C -E: DEVNAME=/dev/bus/usb/001/001 +P: /devices/pci0000:00/0000:00:14.0/usb3 +N: bus/usb/003/001=12010002090001406B1D020015050302010109021900010100E0000904000001090000000705810304000C +E: DEVNAME=/dev/bus/usb/003/001 E: DEVTYPE=usb_device E: DRIVER=usb -E: PRODUCT=1d6b/2/517 +E: PRODUCT=1d6b/2/515 E: TYPE=9/0/1 -E: BUSNUM=001 +E: BUSNUM=003 E: DEVNUM=001 E: MAJOR=189 -E: MINOR=0 +E: MINOR=256 E: SUBSYSTEM=usb -E: ID_VENDOR=Linux_5.17.12-300.fc36.x86_64_xhci-hcd -E: ID_VENDOR_ENC=Linux\x205.17.12-300.fc36.x86_64\x20xhci-hcd +E: ID_VENDOR=Linux_5.15.0-57-generic_xhci-hcd +E: ID_VENDOR_ENC=Linux\x205.15.0-57-generic\x20xhci-hcd E: ID_VENDOR_ID=1d6b E: ID_MODEL=xHCI_Host_Controller E: ID_MODEL_ENC=xHCI\x20Host\x20Controller E: ID_MODEL_ID=0002 -E: ID_REVISION=0517 -E: ID_SERIAL=Linux_5.17.12-300.fc36.x86_64_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 +E: ID_REVISION=0515 +E: ID_SERIAL=Linux_5.15.0-57-generic_xhci-hcd_xHCI_Host_Controller_0000:00:14.0 E: ID_SERIAL_SHORT=0000:00:14.0 E: ID_BUS=usb E: ID_USB_INTERFACES=:090000: @@ -123,31 +126,35 @@ A: bMaxPacketSize0=64\n A: bMaxPower=0mA\n A: bNumConfigurations=1\n A: bNumInterfaces= 1\n -A: bcdDevice=0517\n +A: bcdDevice=0515\n A: bmAttributes=e0\n -A: busnum=1\n -A: configuration=\n -H: descriptors=12010002090001406B1D020017050302010109021900010100E0000904000001090000000705810304000C -A: dev=189:0\n +A: busnum=3\n +A: configuration= +H: descriptors=12010002090001406B1D020015050302010109021900010100E0000904000001090000000705810304000C +A: dev=189:256\n A: devnum=1\n A: devpath=0\n L: driver=../../../../bus/usb/drivers/usb -L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c/device:1d +L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:13/device:14 A: idProduct=0002\n A: idVendor=1d6b\n A: interface_authorized_default=1\n A: ltm_capable=no\n -A: manufacturer=Linux 5.17.12-300.fc36.x86_64 xhci-hcd\n +A: manufacturer=Linux 5.15.0-57-generic xhci-hcd\n A: maxchild=12\n -A: power/active_duration=164289796\n +A: power/active_duration=78971960\n +A: power/async=enabled\n A: power/autosuspend=0\n A: power/autosuspend_delay_ms=0\n -A: power/connected_duration=164360220\n +A: power/connected_duration=78974992\n A: power/control=auto\n A: power/level=auto\n -A: power/runtime_active_time=164331876\n +A: power/runtime_active_kids=2\n +A: power/runtime_active_time=78973899\n +A: power/runtime_enabled=enabled\n A: power/runtime_status=active\n A: power/runtime_suspended_time=0\n +A: power/runtime_usage=0\n A: power/wakeup=disabled\n A: power/wakeup_abort_count=\n A: power/wakeup_active=\n @@ -164,48 +171,52 @@ A: rx_lanes=1\n A: serial=0000:00:14.0\n A: speed=480\n A: tx_lanes=1\n -A: urbnum=2097\n +A: urbnum=1824\n A: version= 2.00\n P: /devices/pci0000:00/0000:00:14.0 E: DRIVER=xhci_hcd E: PCI_CLASS=C0330 -E: PCI_ID=8086:9DED -E: PCI_SUBSYS_ID=17AA:2292 +E: PCI_ID=8086:51ED +E: PCI_SUBSYS_ID=1028:0B00 E: PCI_SLOT_NAME=0000:00:14.0 -E: MODALIAS=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30 +E: MODALIAS=pci:v00008086d000051EDsv00001028sd00000B00bc0Csc03i30 E: SUBSYSTEM=pci E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI E: ID_VENDOR_FROM_DATABASE=Intel Corporation -E: ID_AUTOSUSPEND=1 -E: ID_MODEL_FROM_DATABASE=Cannon Point-LP USB 3.1 xHCI Controller A: ari_enabled=0\n A: broken_parity_status=0\n A: class=0x0c0330\n -H: config=8680ED9D060490021130030C00008000040022EA000000000000000000000000000000000000000000000000AA179222000000007000000000000000FF010000FD0134808FC6FF8300000000000000007F6DDC0F00000000F507312600000000316000000000000000000000000000000180C2C1080000000000000000000000059087001803E0FE0000000000000000090014F01000400100000000C10A080000080E00001800008F40020000010000000000000000000008000000040000000000000000000000000000000000000000000000000000000800000004000000000000000000000000000000000000000000000000000000B50F320112000000 +H: config=8680ED51060490020130030C0000800004002A8F6200000000000000000000000000000000000000000000002810000B000000007000000000000000FF010000FD0134A089C27F8000000000000000003F6DD80F000000000000000000000000316000000000000000000000000000000180C2C1080000000000000000000000059087003808E0FE000000000000000009B014F01000400100000000C10A080000080E00001800008F50020000010000090000018680C00009001014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B50F100112000000 A: consistent_dma_mask_bits=64\n A: d3cold_allowed=1\n A: dbc=disabled\n -A: device=0x9ded\n +A: device=0x51ed\n A: dma_mask_bits=64\n L: driver=../../../bus/pci/drivers/xhci_hcd A: driver_override=(null)\n A: enable=1\n -L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:1c -A: irq=128\n -A: local_cpulist=0-7\n -A: local_cpus=ff\n -A: modalias=pci:v00008086d00009DEDsv000017AAsd00002292bc0Csc03i30\n +L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:13 +L: iommu=../../virtual/iommu/dmar1 +L: iommu_group=../../../kernel/iommu_groups/13 +A: irq=167\n +A: local_cpulist=0-19\n +A: local_cpus=fffff\n +A: modalias=pci:v00008086d000051EDsv00001028sd00000B00bc0Csc03i30\n A: msi_bus=1\n -A: msi_irqs/128=msi\n +A: msi_irqs/167=msi\n A: numa_node=-1\n -A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 11 12 2112 12\nxHCI ring segments 46 50 4096 50\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 6 32 128 1\nbuffer-32 0 0 32 0\n +A: pools=poolinfo - 0.1\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 13 14 2112 14\nxHCI ring segments 38 42 4096 42\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 3 32 128 1\nbuffer-32 0 0 32 0\n +A: power/async=enabled\n A: power/control=auto\n -A: power/runtime_active_time=164332777\n +A: power/runtime_active_kids=1\n +A: power/runtime_active_time=78974886\n +A: power/runtime_enabled=enabled\n A: power/runtime_status=active\n A: power/runtime_suspended_time=0\n +A: power/runtime_usage=0\n A: power/wakeup=enabled\n A: power/wakeup_abort_count=0\n A: power/wakeup_active=0\n @@ -216,9 +227,9 @@ A: power/wakeup_last_time_ms=0\n A: power/wakeup_max_time_ms=0\n A: power/wakeup_total_time_ms=0\n A: power_state=D0\n -A: resource=0x00000000ea220000 0x00000000ea22ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n -A: revision=0x11\n -A: subsystem_device=0x2292\n -A: subsystem_vendor=0x17aa\n +A: resource=0x000000628f2a0000 0x000000628f2affff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n +A: revision=0x01\n +A: subsystem_device=0x0b00\n +A: subsystem_vendor=0x1028\n A: vendor=0x8086\n diff --git a/tests/libfprint.supp b/tests/libfprint.supp index 30a41454..f2acc71a 100644 --- a/tests/libfprint.supp +++ b/tests/libfprint.supp @@ -17,3 +17,10 @@ ... } +{ + + Memcheck:Leak + fun:calloc + ... + fun:g_thread_new +} diff --git a/tests/meson.build b/tests/meson.build index 4dcae66e..fe87ef0f 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -4,9 +4,9 @@ envs.set('G_DEBUG', 'fatal-warnings') envs.set('G_MESSAGES_DEBUG', 'all') # Setup paths -envs.set('MESON_SOURCE_ROOT', meson.source_root()) -envs.set('MESON_BUILD_ROOT', meson.build_root()) -envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint')) +envs.set('MESON_SOURCE_ROOT', meson.project_source_root()) +envs.set('MESON_BUILD_ROOT', meson.project_build_root()) +envs.prepend('LD_LIBRARY_PATH', meson.project_build_root() / 'libfprint') # Set FP_DEVICE_EMULATION so that drivers can adapt (e.g. to use fixed # random numbers rather than proper ones) @@ -19,8 +19,17 @@ envs.set('FP_DRIVERS_WHITELIST', ':'.join([ 'virtual_device_storage', ])) +envs.set('FP_PRINTS_PATH', meson.project_source_root() / 'examples' / 'prints') + envs.set('NO_AT_BRIDGE', '1') +python3 = find_program('python3') + +installed_tests = get_option('installed-tests') +installed_tests_execdir = libexecdir / 'installed-tests' / versioned_libname +installed_tests_testdir = datadir / 'installed-tests' / versioned_libname +installed_tests_libdir = libdir + drivers_tests = [ 'aes2501', 'aes3500', @@ -30,6 +39,7 @@ drivers_tests = [ 'elanspi', 'synaptics', 'upektc_img', + 'upektc_img-tcs1s', 'uru4000-msv2', 'uru4000-4500', 'vfs0050', @@ -44,23 +54,33 @@ drivers_tests = [ if get_option('introspection') conf = configuration_data() - conf.set('SRCDIR', meson.source_root()) - conf.set('BUILDDIR', meson.build_root()) + conf.set('SRCDIR', meson.project_source_root()) + conf.set('BUILDDIR', meson.project_build_root()) configure_file(configuration: conf, input: 'create-driver-test.py.in', output: 'create-driver-test.py') endif +env_parser_cmd = ''' +import os; +print(" ".join([f"{k}={v}" for k, v in os.environ.items() + if k.startswith("FP_") or k.startswith("G_")])) +''' + +envs_str = run_command(python3, '-c', env_parser_cmd, + env: envs, + check: installed_tests).stdout().strip() + if get_option('introspection') - envs.prepend('GI_TYPELIB_PATH', join_paths(meson.build_root(), 'libfprint')) + envs.prepend('GI_TYPELIB_PATH', meson.project_build_root() / 'libfprint') virtual_devices_tests = [ 'virtual-image', 'virtual-device', ] - python3 = find_program('python3') unittest_inspector = find_program('unittest_inspector.py') - umockdev_test = find_program('umockdev-test.py') + umockdev_test_name = 'umockdev-test.py' + umockdev_test = find_program(umockdev_test_name) foreach vdtest: virtual_devices_tests driver_name = '_'.join(vdtest.split('-')) @@ -92,6 +112,30 @@ if get_option('introspection') env: envs, ) endforeach + + if installed_tests + install_data(base_args, + install_dir: installed_tests_execdir, + install_mode: 'rwxr-xr-x', + ) + + configure_file( + input: 'test.in', + output: vdtest + '.test', + install_dir: installed_tests_testdir, + configuration: { + # FIXME: use fs.name() on meson 0.58 + 'exec': installed_tests_execdir / '@0@'.format(base_args[0]).split('/')[-1], + 'env': ' '.join([ + envs_str, + 'LD_LIBRARY_PATH=' + installed_tests_libdir, + 'FP_PRINTS_PATH=' + installed_tests_testdir / 'prints', + # FIXME: Adding this requires gnome-desktop-testing!12 + ]), + 'extra_content': '', + }, + ) + endif else test(vdtest, find_program('sh'), @@ -100,6 +144,7 @@ if get_option('introspection') endif endforeach + driver_tests_enabled = false foreach driver_test: drivers_tests driver_name = driver_test.split('-')[0] driver_envs = envs @@ -107,6 +152,7 @@ if get_option('introspection') if (driver_name in supported_drivers and gusb_dep.version().version_compare('>= 0.3.0')) + driver_tests_enabled = true test(driver_test, python3, args: [ @@ -118,6 +164,32 @@ if get_option('introspection') timeout: 15, depends: libfprint_typelib, ) + + if installed_tests + driver_envs_str = run_command(python3, '-c', env_parser_cmd, + env: driver_envs, + check: true).stdout().strip() + + configure_file( + input: 'driver.test.in', + output: 'driver-' + driver_test + '.test', + install_dir: installed_tests_testdir, + configuration: { + 'installed_tests_execdir': installed_tests_execdir, + 'installed_tests_testdir': installed_tests_testdir, + 'umockdev_test_name': umockdev_test_name, + 'driver_test': driver_test, + 'driver_env': ' '.join([ + driver_envs_str, + 'LD_LIBRARY_PATH=' + installed_tests_libdir, + # FIXME: Adding this requires gnome-desktop-testing!12 + # 'GI_TYPELIB_PATH=' + installed_tests_libdir / 'girepository-1.0', + ]), + }, + ) + + install_subdir(driver_test, install_dir: installed_tests_testdir) + endif else test(driver_test, find_program('sh'), @@ -125,6 +197,17 @@ if get_option('introspection') ) endif endforeach + + if installed_tests and driver_tests_enabled + install_data(umockdev_test.full_path(), + install_dir: installed_tests_execdir, + install_mode: 'rwxr-xr-x', + ) + install_data('capture.py', + install_dir: installed_tests_execdir, + install_mode: 'rwxr-xr-x', + ) + endif else warning('Skipping all driver tests as introspection bindings are missing') test('virtual-image', @@ -164,7 +247,7 @@ endif unit_tests_deps = { 'fpi-assembling' : [cairo_dep] } test_config = configuration_data() -test_config.set_quoted('SOURCE_ROOT', meson.source_root()) +test_config.set_quoted('SOURCE_ROOT', meson.project_source_root()) test_config_h = configure_file(output: 'test-config.h', configuration: test_config) foreach test_name: unit_tests @@ -197,13 +280,28 @@ foreach test_name: unit_tests sources: [basename + '.c', test_config_h], dependencies: [ libfprint_private_dep ] + extra_deps, c_args: common_cflags, - link_with: test_utils, + link_whole: test_utils, + install: installed_tests, + install_dir: installed_tests_execdir, ) test(test_name, test_exe, suite: ['unit-tests'], env: envs, ) + + configure_file( + input: 'test.in', + output: test_name + '.test', + install: installed_tests, + install_dir: installed_tests_testdir, + configuration: { + 'exec': installed_tests_execdir / basename, + 'env': envs_str, + 'extra_content': 'TestEnvironment=LD_LIBRARY_PATH=' + + installed_tests_libdir, + }, + ) endforeach # Run udev rule generator with fatal warnings @@ -217,7 +315,7 @@ test('udev-hwdb', gdb = find_program('gdb', required: false) if gdb.found() libfprint_wrapper = [ - gdb.path(), + gdb.full_path(), '-batch', '-ex', 'run', '--args', @@ -234,12 +332,12 @@ valgrind = find_program('valgrind', required: false) if valgrind.found() glib_share = glib_dep.get_pkgconfig_variable('prefix') / 'share' / glib_dep.name() glib_suppressions = glib_share + '/valgrind/glib.supp' - libfprint_suppressions = '@0@/@1@'.format(meson.source_root(), + libfprint_suppressions = '@0@/@1@'.format(meson.project_source_root(), files('libfprint.supp')[0]) - python_suppressions = '@0@/@1@'.format(meson.source_root(), + python_suppressions = '@0@/@1@'.format(meson.project_source_root(), files('valgrind-python.supp')[0]) libfprint_wrapper = [ - valgrind.path(), + valgrind.full_path(), '--tool=memcheck', '--leak-check=full', '--leak-resolution=high', @@ -248,6 +346,7 @@ if valgrind.found() '--track-origins=yes', '--show-leak-kinds=definite,possible', '--show-error-list=yes', + '--gen-suppressions=all', '--suppressions=' + libfprint_suppressions, '--suppressions=' + glib_suppressions, '--suppressions=' + python_suppressions, @@ -344,7 +443,7 @@ if get_option('tod') ] foreach tod_version: tod_test_versions - tod_dir = meson.current_source_dir() / 'tod-drivers' / '-'.join([ + tod_dir = 'tod-drivers' / '-'.join([ 'tod', host_machine.cpu_family(), tod_version ]) tod_driver_infos += { @@ -364,6 +463,11 @@ if get_option('tod') ], } } + + if installed_tests + install_subdir(tod_dir, + install_dir: installed_tests_execdir / 'tod-drivers') + endif endforeach endif @@ -379,6 +483,8 @@ if get_option('tod') common_cflags, tod_c_args, ], + install: installed_tests, + install_dir: installed_tests_execdir, link_with: test_utils_tod, ) @@ -388,7 +494,8 @@ if get_option('tod') endif tod_test_envs = tod_envs tod_test_envs.prepend('FP_DRIVERS_WHITELIST', tod_driver) - tod_test_envs.set('FP_TOD_DRIVERS_DIR', tod_driver_info.get('tod-dir')) + tod_test_envs.set('FP_TOD_DRIVERS_DIR', meson.current_source_dir() / + tod_driver_info.get('tod-dir')) tod_test_envs.set('FP_TOD_TEST_DRIVER_NAME', tod_driver) test(tod_test_name + '-' + tod_driver, @@ -397,6 +504,28 @@ if get_option('tod') env: tod_test_envs, depends: fake_driver, ) + + if installed_tests + tod_envs_str = run_command(python3, '-c', env_parser_cmd, + env: tod_test_envs, + check: true).stdout().strip() + + configure_file( + input: 'test.in', + output: 'tod-' + tod_test_name + '-' + tod_driver + '.test', + install_dir: installed_tests_testdir, + configuration: { + # FIXME: use fs.name() on meson 0.58 + 'exec': installed_tests_execdir / test_exe.full_path().split('/')[-1], + 'env': ' '.join([ + tod_envs_str, + 'FP_TOD_DRIVERS_DIR=' + installed_tests_execdir / + tod_driver_info.get('tod-dir'), + ]), + 'extra_content': '', + }, + ) + endif endforeach if test_name in tod_standalone_tests diff --git a/tests/test-fp-todv1-types.c b/tests/test-fp-todv1-types.c index 34582b97..6b7b5eeb 100644 --- a/tests/test-fp-todv1-types.c +++ b/tests/test-fp-todv1-types.c @@ -102,23 +102,23 @@ check_compatiblity_auto (GType old_type, GType current_type) } #define check_type_compatibility(type, major, minor, micro) \ - g_debug ("Checking " # type " @ " G_STRLOC); \ - check_compatiblity_auto (type ## _TOD_V ## major ## _ ## minor ## _ ## micro, type); + g_debug ("Checking " # type " @ " G_STRLOC); \ + check_compatiblity_auto (type ## _TOD_V ## major ## _ ## minor ## _ ## micro, type); #define tod_versioned_type(type, major, minor, micro) \ - type ## TODV ## major ## _ ## minor ## _ ## micro + type ## TODV ## major ## _ ## minor ## _ ## micro #define check_struct_size(type, major, minor, micro) \ - g_debug ("Checking " # type " v" #major "." #minor "." #micro " size @ " G_STRLOC); \ - g_assert_cmpuint (sizeof (tod_versioned_type (type, major, minor, micro)), \ - ==, \ - sizeof (type)) + g_debug ("Checking " # type " v" #major "." #minor "." #micro " size @ " G_STRLOC); \ + g_assert_cmpuint (sizeof (tod_versioned_type (type, major, minor, micro)), \ + ==, \ + sizeof (type)) #define check_struct_member(type, major, minor, micro, member) \ - g_debug ("Checking " # type " v" #major "." #minor "." #micro "'s " # member " offset @ " G_STRLOC); \ - g_assert_cmpuint (G_STRUCT_OFFSET (tod_versioned_type (type, major, minor, micro), member), \ - ==, \ - G_STRUCT_OFFSET (type, member)) + g_debug ("Checking " # type " v" #major "." #minor "." #micro "'s " # member " offset @ " G_STRLOC); \ + g_assert_cmpuint (G_STRUCT_OFFSET (tod_versioned_type (type, major, minor, micro), member), \ + ==, \ + G_STRUCT_OFFSET (type, member)) static void test_device_type (void) diff --git a/tests/test-fpi-device.c b/tests/test-fpi-device.c index 19fadba4..9daf7f2e 100644 --- a/tests/test-fpi-device.c +++ b/tests/test-fpi-device.c @@ -144,8 +144,10 @@ tod_check_device_version (FpDevice *device_class, } /* gcc 12.0.1 is complaining about dangling pointers in the auto_close* functions */ +#if G_GNUC_CHECK_VERSION (12, 0) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdangling-pointer" +#endif /* Utility functions */ @@ -187,7 +189,9 @@ auto_close_fake_device_free (FpAutoCloseDevice *device) } G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpAutoCloseDevice, auto_close_fake_device_free) +#if G_GNUC_CHECK_VERSION (12, 0) #pragma GCC diagnostic pop +#endif typedef FpDeviceClass FpAutoResetClass; static FpAutoResetClass default_fake_dev_class = {0}; diff --git a/tests/test.in b/tests/test.in new file mode 100644 index 00000000..1c8eecb2 --- /dev/null +++ b/tests/test.in @@ -0,0 +1,6 @@ +[Test] +Type=session +# We can't use TestEnvironment as per +# https://gitlab.gnome.org/GNOME/gnome-desktop-testing/-/issues/1 +Exec=env @env@ @exec@ +@extra_content@ diff --git a/tests/upektc_img-tcs1s/capture.pcapng b/tests/upektc_img-tcs1s/capture.pcapng new file mode 100644 index 00000000..94f63341 Binary files /dev/null and b/tests/upektc_img-tcs1s/capture.pcapng differ diff --git a/tests/upektc_img-tcs1s/capture.png b/tests/upektc_img-tcs1s/capture.png new file mode 100644 index 00000000..cf510a54 Binary files /dev/null and b/tests/upektc_img-tcs1s/capture.png differ diff --git a/tests/upektc_img-tcs1s/device b/tests/upektc_img-tcs1s/device new file mode 100644 index 00000000..10cf6ae5 --- /dev/null +++ b/tests/upektc_img-tcs1s/device @@ -0,0 +1,308 @@ +P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3/3-2 +N: bus/usb/003/004=12011001000000087E14162002000102000109022700010100A0320904000003FF000000070581024000000705020240000007058303040014 +E: BUSNUM=003 +E: CURRENT_TAGS=:seat: +E: DEVNAME=/dev/bus/usb/003/004 +E: DEVNUM=004 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: ID_AUTOSUSPEND=1 +E: ID_BUS=usb +E: ID_FOR_SEAT=usb-pci-0000_05_00_4-usb-0_2 +E: ID_MODEL=Biometric_Coprocessor +E: ID_MODEL_ENC=Biometric\x20Coprocessor +E: ID_MODEL_FROM_DATABASE=Biometric Touchchip/Touchstrip Fingerprint Sensor +E: ID_MODEL_ID=2016 +E: ID_PATH=pci-0000:05:00.4-usb-0:2 +E: ID_PATH_TAG=pci-0000_05_00_4-usb-0_2 +E: ID_PERSIST=0 +E: ID_REVISION=0002 +E: ID_SERIAL=UPEK_Biometric_Coprocessor +E: ID_USB_INTERFACES=:ff0000: +E: ID_VENDOR=UPEK +E: ID_VENDOR_ENC=UPEK +E: ID_VENDOR_FROM_DATABASE=Upek +E: ID_VENDOR_ID=147e +E: MAJOR=189 +E: MINOR=259 +E: PRODUCT=147e/2016/2 +E: SUBSYSTEM=usb +E: TAGS=:seat: +E: TYPE=0/0/0 +A: authorized=1\n +A: avoid_reset_quirk=0\n +A: bConfigurationValue=1\n +A: bDeviceClass=00\n +A: bDeviceProtocol=00\n +A: bDeviceSubClass=00\n +A: bMaxPacketSize0=8\n +A: bMaxPower=100mA\n +A: bNumConfigurations=1\n +A: bNumInterfaces= 1\n +A: bcdDevice=0002\n +A: bmAttributes=a0\n +A: busnum=3\n +A: configuration= +H: descriptors=12011001000000087E14162002000102000109022700010100A0320904000003FF000000070581024000000705020240000007058303040014 +A: dev=189:259\n +A: devnum=4\n +A: devpath=2\n +L: driver=../../../../../../bus/usb/drivers/usb +L: firmware_node=../../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:10/device:1f/device:20/device:22 +A: idProduct=2016\n +A: idVendor=147e\n +A: ltm_capable=no\n +A: manufacturer=UPEK\n +A: maxchild=0\n +A: physical_location/dock=no\n +A: physical_location/horizontal_position=left\n +A: physical_location/lid=no\n +A: physical_location/panel=top\n +A: physical_location/vertical_position=upper\n +L: port=../3-0:1.0/usb3-port2 +A: power/active_duration=76426\n +A: power/autosuspend=2\n +A: power/autosuspend_delay_ms=2000\n +A: power/connected_duration=5956377\n +A: power/control=auto\n +A: power/level=auto\n +A: power/persist=0\n +A: power/runtime_active_time=77623\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=5878510\n +A: power/wakeup=disabled\n +A: power/wakeup_abort_count=\n +A: power/wakeup_active=\n +A: power/wakeup_active_count=\n +A: power/wakeup_count=\n +A: power/wakeup_expire_count=\n +A: power/wakeup_last_time_ms=\n +A: power/wakeup_max_time_ms=\n +A: power/wakeup_total_time_ms=\n +A: product=Biometric Coprocessor\n +A: quirks=0x0\n +A: removable=removable\n +A: rx_lanes=1\n +A: speed=12\n +A: tx_lanes=1\n +A: urbnum=1200\n +A: version= 1.10\n + +P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb3 +N: bus/usb/003/001=12010002090001406B1D020019050302010109021900010100E0000904000001090000000705810304000C +E: BUSNUM=003 +E: CURRENT_TAGS=:seat: +E: DEVNAME=/dev/bus/usb/003/001 +E: DEVNUM=001 +E: DEVTYPE=usb_device +E: DRIVER=usb +E: ID_AUTOSUSPEND=1 +E: ID_BUS=usb +E: ID_FOR_SEAT=usb-pci-0000_05_00_4 +E: ID_MODEL=xHCI_Host_Controller +E: ID_MODEL_ENC=xHCI\x20Host\x20Controller +E: ID_MODEL_FROM_DATABASE=2.0 root hub +E: ID_MODEL_ID=0002 +E: ID_PATH=pci-0000:05:00.4 +E: ID_PATH_TAG=pci-0000_05_00_4 +E: ID_REVISION=0519 +E: ID_SERIAL=Linux_5.19.14-200.fc36.x86_64_xhci-hcd_xHCI_Host_Controller_0000:05:00.4 +E: ID_SERIAL_SHORT=0000:05:00.4 +E: ID_USB_INTERFACES=:090000: +E: ID_VENDOR=Linux_5.19.14-200.fc36.x86_64_xhci-hcd +E: ID_VENDOR_ENC=Linux\x205.19.14-200.fc36.x86_64\x20xhci-hcd +E: ID_VENDOR_FROM_DATABASE=Linux Foundation +E: ID_VENDOR_ID=1d6b +E: MAJOR=189 +E: MINOR=256 +E: PRODUCT=1d6b/2/519 +E: SUBSYSTEM=usb +E: TAGS=:seat: +E: TYPE=9/0/1 +A: authorized=1\n +A: authorized_default=1\n +A: avoid_reset_quirk=0\n +A: bConfigurationValue=1\n +A: bDeviceClass=09\n +A: bDeviceProtocol=01\n +A: bDeviceSubClass=00\n +A: bMaxPacketSize0=64\n +A: bMaxPower=0mA\n +A: bNumConfigurations=1\n +A: bNumInterfaces= 1\n +A: bcdDevice=0519\n +A: bmAttributes=e0\n +A: busnum=3\n +A: configuration= +H: descriptors=12010002090001406B1D020019050302010109021900010100E0000904000001090000000705810304000C +A: dev=189:256\n +A: devnum=1\n +A: devpath=0\n +L: driver=../../../../../bus/usb/drivers/usb +L: firmware_node=../../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:10/device:1f/device:20 +A: idProduct=0002\n +A: idVendor=1d6b\n +A: interface_authorized_default=1\n +A: ltm_capable=no\n +A: manufacturer=Linux 5.19.14-200.fc36.x86_64 xhci-hcd\n +A: maxchild=4\n +A: power/active_duration=95134\n +A: power/autosuspend=0\n +A: power/autosuspend_delay_ms=0\n +A: power/connected_duration=6808009\n +A: power/control=auto\n +A: power/level=auto\n +A: power/runtime_active_time=95126\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=6712879\n +A: power/wakeup=disabled\n +A: power/wakeup_abort_count=\n +A: power/wakeup_active=\n +A: power/wakeup_active_count=\n +A: power/wakeup_count=\n +A: power/wakeup_expire_count=\n +A: power/wakeup_last_time_ms=\n +A: power/wakeup_max_time_ms=\n +A: power/wakeup_total_time_ms=\n +A: product=xHCI Host Controller\n +A: quirks=0x0\n +A: removable=unknown\n +A: rx_lanes=1\n +A: serial=0000:05:00.4\n +A: speed=480\n +A: tx_lanes=1\n +A: urbnum=441\n +A: version= 2.00\n + +P: /devices/pci0000:00/0000:00:08.1/0000:05:00.4 +E: DRIVER=xhci_hcd +E: ID_MODEL_FROM_DATABASE=Renoir/Cezanne USB 3.1 +E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller +E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI +E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller +E: ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. [AMD] +E: MODALIAS=pci:v00001022d00001639sv00001043sd0000201Fbc0Csc03i30 +E: PCI_CLASS=C0330 +E: PCI_ID=1022:1639 +E: PCI_SLOT_NAME=0000:05:00.4 +E: PCI_SUBSYS_ID=1043:201F +E: SUBSYSTEM=pci +A: ari_enabled=0\n +A: broken_parity_status=0\n +A: class=0x0c0330\n +H: config=22103916070410000030030C10008000040020FC00000000000000000000000000000000000000000000000043101F20000000004800000000000000FF01000000000000000000000950080043101F20016403C80000000000000000000000003120000010A00200A18F000030290000040D400040000411000000000000000000000000000000001F007100000000001E00800100000100000000000000000005C08600000000000000000000000000000000000000000000000000000000001100078000E00F0000F00F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0001000100010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +A: consistent_dma_mask_bits=64\n +A: current_link_speed=16.0 GT/s PCIe\n +A: current_link_width=16\n +A: d3cold_allowed=1\n +A: dbc=disabled\n +A: device=0x1639\n +A: dma_mask_bits=64\n +L: driver=../../../../bus/pci/drivers/xhci_hcd +A: driver_override=(null)\n +A: enable=1\n +L: firmware_node=../../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:10/device:1f +L: iommu=../../0000:00:00.2/iommu/ivhd0 +L: iommu_group=../../../../kernel/iommu_groups/6 +A: irq=45\n +A: link/l0s_aspm=0\n +A: link/l1_aspm=0\n +A: local_cpulist=0-15\n +A: local_cpus=ffff\n +A: max_link_speed=16.0 GT/s PCIe\n +A: max_link_width=16\n +A: modalias=pci:v00001022d00001639sv00001043sd0000201Fbc0Csc03i30\n +A: msi_bus=1\n +A: msi_irqs/46=msix\n +A: msi_irqs/47=msix\n +A: msi_irqs/48=msix\n +A: msi_irqs/49=msix\n +A: msi_irqs/50=msix\n +A: msi_irqs/51=msix\n +A: msi_irqs/52=msix\n +A: msi_irqs/53=msix\n +A: numa_node=-1\n +A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 4 5 2112 5\nxHCI ring segments 22 26 4096 26\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\n +A: power/control=on\n +A: power/runtime_active_time=6808494\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=0\n +A: power/wakeup=enabled\n +A: power/wakeup_abort_count=0\n +A: power/wakeup_active=0\n +A: power/wakeup_active_count=0\n +A: power/wakeup_count=0\n +A: power/wakeup_expire_count=0\n +A: power/wakeup_last_time_ms=0\n +A: power/wakeup_max_time_ms=0\n +A: power/wakeup_total_time_ms=0\n +A: power_state=D0\n +A: reset_method=pm\n +A: resource=0x00000000fc200000 0x00000000fc2fffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n +A: revision=0x00\n +A: subsystem_device=0x201f\n +A: subsystem_vendor=0x1043\n +A: vendor=0x1022\n + +P: /devices/pci0000:00/0000:00:08.1 +E: DRIVER=pcieport +E: ID_MODEL_FROM_DATABASE=Renoir Internal PCIe GPP Bridge to Bus +E: ID_PCI_CLASS_FROM_DATABASE=Bridge +E: ID_PCI_INTERFACE_FROM_DATABASE=Normal decode +E: ID_PCI_SUBCLASS_FROM_DATABASE=PCI bridge +E: ID_VENDOR_FROM_DATABASE=Advanced Micro Devices, Inc. [AMD] +E: MODALIAS=pci:v00001022d00001635sv00001022sd00001635bc06sc04i00 +E: PCI_CLASS=60400 +E: PCI_ID=1022:1635 +E: PCI_SLOT_NAME=0000:00:08.1 +E: PCI_SUBSYS_ID=1022:1635 +E: SUBSYSTEM=pci +A: ari_enabled=0\n +A: broken_parity_status=0\n +A: class=0x060400\n +H: config=22103516070410000000040610008100000000000000000000050500C1C1000020FC50FC01D011E00000000000000000000000005000000000000000FF01120000000000000000000000000000000000015803C80000000010A042002280000030290000040D7000400004710000000000004000180001000000000000003100000000001E00800144001F00000000000000000000000000000000000000000005C081000000E0FE0000000000000000000000000000000000000000000000000D000000221035160000000000000000000000000000000000000000000000000000000034B205000000000000000000000000000000000000000000000000000B000127010001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001900014000000000000000007F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000250001410100008001000080000000002600014400000000000000000F00000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2700010000000000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C0000389C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +A: consistent_dma_mask_bits=32\n +A: current_link_speed=16.0 GT/s PCIe\n +A: current_link_width=16\n +A: d3cold_allowed=1\n +A: device=0x1635\n +A: dma_mask_bits=32\n +L: driver=../../../bus/pci/drivers/pcieport +A: driver_override=(null)\n +A: enable=2\n +L: firmware_node=../../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:10 +L: iommu=../0000:00:00.2/iommu/ivhd0 +L: iommu_group=../../../kernel/iommu_groups/6 +A: irq=30\n +A: local_cpulist=0-15\n +A: local_cpus=ffff\n +A: max_link_speed=16.0 GT/s PCIe\n +A: max_link_width=16\n +A: modalias=pci:v00001022d00001635sv00001022sd00001635bc06sc04i00\n +A: msi_bus=1\n +A: msi_irqs/30=msi\n +A: numa_node=-1\n +A: power/autosuspend_delay_ms=100\n +A: power/control=auto\n +A: power/runtime_active_time=6808508\n +A: power/runtime_status=active\n +A: power/runtime_suspended_time=0\n +A: power/wakeup=enabled\n +A: power/wakeup_abort_count=0\n +A: power/wakeup_active=0\n +A: power/wakeup_active_count=0\n +A: power/wakeup_count=0\n +A: power/wakeup_expire_count=0\n +A: power/wakeup_last_time_ms=0\n +A: power/wakeup_max_time_ms=0\n +A: power/wakeup_total_time_ms=0\n +A: power_state=D0\n +A: reset_method=pm\n +A: resource=0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x000000000000c000 0x000000000000cfff 0x0000000000000101\n0x00000000fc200000 0x00000000fc5fffff 0x0000000000000200\n0x00000000d0000000 0x00000000e01fffff 0x0000000000102201\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n +A: revision=0x00\n +A: secondary_bus_number=5\n +A: subordinate_bus_number=5\n +A: subsystem_device=0x1635\n +A: subsystem_vendor=0x1022\n +A: vendor=0x1022\n + diff --git a/tests/valgrind-python.supp b/tests/valgrind-python.supp index 395e8015..59e21858 100644 --- a/tests/valgrind-python.supp +++ b/tests/valgrind-python.supp @@ -40,6 +40,20 @@ fun:_Py* } +{ + ignore__py_addr32 + Memcheck:Addr32 + ... + fun:_Py* +} + +{ + ignore__py_addr32 + Memcheck:Addr32 + ... + fun:Py* +} + { ignore_py_leaks Memcheck:Leak diff --git a/tests/virtual-device.py b/tests/virtual-device.py index 4dc8e56e..46981e01 100644 --- a/tests/virtual-device.py +++ b/tests/virtual-device.py @@ -59,6 +59,17 @@ class GLibErrorMessage: class VirtualDeviceBase(unittest.TestCase): + DEFAULT_ENROLL_STEPS = 5 + USE_CLASS_DEVICE = True + + @classmethod + def get_device(cls, ctx): + for dev in ctx.get_devices(): + # We might have a USB device in the test system that needs skipping + if dev.get_driver() == cls._driver_name: + return dev + return None + @classmethod def setUpClass(cls): unittest.TestCase.setUpClass() @@ -73,26 +84,28 @@ class VirtualDeviceBase(unittest.TestCase): cls.sockaddr = os.path.join(cls.tmpdir, '{}.socket'.format(sock_name)) os.environ['FP_{}'.format(driver_name.upper())] = cls.sockaddr - cls.ctx = FPrint.Context() + cls._driver_name = driver_name - cls.dev = None - for dev in cls.ctx.get_devices(): - # We might have a USB device in the test system that needs skipping - if dev.get_driver() == driver_name: - cls.dev = dev - break - - assert cls.dev is not None, "You need to compile with {} for testing".format(driver_name) + if cls.USE_CLASS_DEVICE: + cls.ctx = FPrint.Context() + cls.dev = cls.get_device(cls.ctx) + assert cls.dev is not None, "You need to compile with {} for testing".format( + driver_name) @classmethod def tearDownClass(cls): shutil.rmtree(cls.tmpdir) - del cls.dev - del cls.ctx + if cls.USE_CLASS_DEVICE: + del cls.dev + del cls.ctx unittest.TestCase.tearDownClass() def setUp(self): super().setUp() + if not self.USE_CLASS_DEVICE: + self.ctx = FPrint.Context() + self.dev = self.get_device(self.ctx) + self.assertIsNotNone(self.dev) self._close_on_teardown = True self.assertFalse(self.dev.is_open()) self.dev.open_sync() @@ -101,8 +114,13 @@ class VirtualDeviceBase(unittest.TestCase): def tearDown(self): if self._close_on_teardown: self.assertTrue(self.dev.is_open()) + self.set_keep_alive(False) + self.send_command('SET_ENROLL_STAGES', self.DEFAULT_ENROLL_STEPS) self.dev.close_sync() self.assertFalse(self.dev.is_open()) + if not self.USE_CLASS_DEVICE: + del self.dev + del self.ctx super().tearDown() def wait_timeout(self, interval): @@ -331,6 +349,107 @@ class VirtualDeviceBase(unittest.TestCase): self.assertEqual(self._verify_fp.props.fpi_data.get_string(), scan_nick) +class VirtualDeviceUnplugging(VirtualDeviceBase): + + driver_name = 'virtual_device' + USE_CLASS_DEVICE = False + + def test_device_unplug(self): + self._close_on_teardown = False + notified_spec = None + def on_removed_notify(dev, spec): + nonlocal notified_spec + notified_spec = spec + + removed = False + ctx_removed = False + + def on_ctx_removed(ctx, dev): + nonlocal ctx_removed + ctx_removed = dev == self.dev + self.assertEqual(removed, ctx_removed) + + def on_removed(dev): + nonlocal removed + removed = dev.props.removed + self.assertNotEqual(removed, ctx_removed) + + self.assertFalse(self.dev.props.removed) + + self.dev.connect('notify::removed', on_removed_notify) + self.ctx.connect('device-removed', on_ctx_removed) + self.dev.connect('removed', on_removed) + self.send_command('UNPLUG') + self.assertEqual(notified_spec.name, 'removed') + self.assertTrue(self.dev.props.removed) + self.assertIn(self.dev, self.ctx.get_devices()) + self.assertTrue(removed) + + with self.assertRaises(GLib.GError) as error: + self.dev.close_sync() + self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), + FPrint.DeviceError.REMOVED)) + + while not ctx_removed: + ctx.iteration(True) + + self.assertNotIn(self.dev, self.ctx.get_devices()) + + def test_device_unplug_during_verify(self): + self._close_on_teardown = False + self._destroy_on_teardown = True + + notified_spec = None + def on_removed_notify(dev, spec): + nonlocal notified_spec + notified_spec = spec + + removed = False + ctx_removed = False + + def on_ctx_removed(ctx, dev): + nonlocal ctx_removed + ctx_removed = dev == self.dev + self.assertEqual(removed, ctx_removed) + + def on_removed(dev): + nonlocal removed + removed = dev.props.removed + self.assertNotEqual(removed, ctx_removed) + + self.assertFalse(self.dev.props.removed) + self.dev.connect('notify::removed', on_removed_notify) + self.ctx.connect('device-removed', on_ctx_removed) + self.dev.connect('removed', on_removed) + + self.start_verify(FPrint.Print.new(self.dev), + identify=self.dev.supports_identify()) + + self.send_command('UNPLUG') + self.assertEqual(notified_spec.name, 'removed') + self.assertTrue(self.dev.props.removed) + self.assertIn(self.dev, self.ctx.get_devices()) + self.assertFalse(removed) + + with self.assertRaises(GLib.GError) as error: + self.complete_verify() + self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), + FPrint.DeviceError.REMOVED)) + + self.assertTrue(removed) + self.assertIn(self.dev, self.ctx.get_devices()) + + with self.assertRaises(GLib.GError) as error: + self.dev.close_sync() + self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), + FPrint.DeviceError.REMOVED)) + + while not ctx_removed: + ctx.iteration(True) + + self.assertNotIn(self.dev, self.ctx.get_devices()) + + class VirtualDevice(VirtualDeviceBase): def test_device_properties(self): @@ -339,7 +458,8 @@ class VirtualDevice(VirtualDeviceBase): self.assertEqual(self.dev.get_name(), 'Virtual device for debugging') self.assertTrue(self.dev.is_open()) self.assertEqual(self.dev.get_scan_type(), FPrint.ScanType.SWIPE) - self.assertEqual(self.dev.get_nr_enroll_stages(), 5) + self.assertEqual(self.dev.get_nr_enroll_stages(), + self.DEFAULT_ENROLL_STEPS) self.assertFalse(self.dev.supports_identify()) self.assertFalse(self.dev.supports_capture()) self.assertFalse(self.dev.has_storage()) @@ -700,69 +820,6 @@ class VirtualDevice(VirtualDeviceBase): self.assertEqual(self.dev.get_scan_type(), FPrint.ScanType.SWIPE) self.assertIsNone(notified_spec) - def test_device_unplug(self): - self._close_on_teardown = False - notified_spec = None - def on_removed_notify(dev, spec): - nonlocal notified_spec - notified_spec = spec - - removed = False - def on_removed(dev): - nonlocal removed - removed = True - - self.assertFalse(self.dev.props.removed) - - self.dev.connect('notify::removed', on_removed_notify) - self.dev.connect('removed', on_removed) - self.send_command('UNPLUG') - self.assertEqual(notified_spec.name, 'removed') - self.assertTrue(self.dev.props.removed) - self.assertTrue(removed) - - with self.assertRaises(GLib.GError) as error: - self.dev.close_sync() - self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), - FPrint.DeviceError.REMOVED)) - - def test_device_unplug_during_verify(self): - self._close_on_teardown = False - - notified_spec = None - def on_removed_notify(dev, spec): - nonlocal notified_spec - notified_spec = spec - - removed = False - def on_removed(dev): - nonlocal removed - removed = True - - self.assertFalse(self.dev.props.removed) - self.dev.connect('notify::removed', on_removed_notify) - self.dev.connect('removed', on_removed) - - self.start_verify(FPrint.Print.new(self.dev), - identify=self.dev.supports_identify()) - - self.send_command('UNPLUG') - self.assertEqual(notified_spec.name, 'removed') - self.assertTrue(self.dev.props.removed) - self.assertFalse(removed) - - with self.assertRaises(GLib.GError) as error: - self.complete_verify() - self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), - FPrint.DeviceError.REMOVED)) - - self.assertTrue(removed) - - with self.assertRaises(GLib.GError) as error: - self.dev.close_sync() - self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), - FPrint.DeviceError.REMOVED)) - def test_device_sleep(self): self.send_sleep(1500) diff --git a/tests/virtual-image.py b/tests/virtual-image.py index 448c4bc1..b3dc746e 100755 --- a/tests/virtual-image.py +++ b/tests/virtual-image.py @@ -46,12 +46,15 @@ def load_image(img): return img -if hasattr(os.environ, 'MESON_SOURCE_ROOT'): - root = os.environ['MESON_SOURCE_ROOT'] +if 'FP_PRINTS_PATH' in os.environ: + prints_path = os.environ['FP_PRINTS_PATH'] else: - root = os.path.join(os.path.dirname(__file__), '..') + if 'MESON_SOURCE_ROOT' in os.environ: + root = os.environ['MESON_SOURCE_ROOT'] + else: + root = os.path.join(os.path.dirname(__file__), '..') -imgdir = os.path.join(root, 'examples', 'prints') + prints_path = os.path.join(root, 'examples', 'prints') ctx = GLib.main_context_default() @@ -76,10 +79,12 @@ class VirtualImage(unittest.TestCase): assert cls.dev is not None, "You need to compile with virtual_image for testing" cls.prints = {} - for f in glob.glob(os.path.join(imgdir, '*.png')): + for f in glob.glob(os.path.join(prints_path, '*.png')): n = os.path.basename(f)[:-4] cls.prints[n] = load_image(f) + assert cls.prints, "No prints found in " + prints_path + @classmethod def tearDownClass(cls): shutil.rmtree(cls.tmpdir)