mirror of
https://gitlab.com/mishakmak/pam-fprint-grosshack.git
synced 2026-04-11 13:23:33 +02:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fc7e058e93 | |||
| ff4ba1da47 | |||
| 626128a0fa | |||
| 0bba073dff | |||
| ec74c849be | |||
| e09d90c81b | |||
| e3b0d52ce5 | |||
| 70182083a1 | |||
| 66e7df1105 | |||
| 96b911913e | |||
| 37e6939fa9 | |||
| bb23b7e9d0 | |||
| 80eb673e83 | |||
| 88d7d97c0d | |||
| 6bc19c8892 | |||
| c690542e7c | |||
| 5f6e80de01 | |||
| 3c8ac241b8 | |||
| 2bf6d6a266 | |||
| be45b44337 | |||
| 572c119fd4 | |||
| 980bab5135 | |||
| 161278cacd | |||
| 2dd1cd8fc3 | |||
| 0de01da150 | |||
| 0844002b78 | |||
| 9ae3c16f2d | |||
| f4995dcabe | |||
| 8c0876ae49 | |||
| 3a96b6f2f0 | |||
| 688f9b0acf | |||
| 5b9e237884 | |||
| 8288c0efc7 | |||
| 0d2dbc6179 |
@ -95,10 +95,11 @@ test_dev:
|
|||||||
- ninja -C _build coverage
|
- ninja -C _build coverage
|
||||||
- cat _build/meson-logs/coverage.txt
|
- cat _build/meson-logs/coverage.txt
|
||||||
artifacts:
|
artifacts:
|
||||||
name: log-and-coverage
|
expose_as: 'Coverage Report'
|
||||||
when: always
|
|
||||||
paths:
|
paths:
|
||||||
- _build/meson-logs
|
- _build/meson-logs
|
||||||
|
- _build/meson-logs/coveragereport/index.html
|
||||||
|
expire_in: 1 week
|
||||||
|
|
||||||
test_dev_with_sanitizer:
|
test_dev_with_sanitizer:
|
||||||
extends:
|
extends:
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
[main]
|
|
||||||
host = https://www.transifex.com
|
|
||||||
|
|
||||||
[fprintd.fprintd-po-fprintd-pot]
|
|
||||||
file_filter = po/<lang>.po
|
|
||||||
source_file = po/fprintd.pot
|
|
||||||
source_lang = en
|
|
||||||
|
|
||||||
18
NEWS
18
NEWS
@ -1,6 +1,24 @@
|
|||||||
This file lists notable changes in each release. For the full history of all
|
This file lists notable changes in each release. For the full history of all
|
||||||
changes, see ChangeLog.
|
changes, see ChangeLog.
|
||||||
|
|
||||||
|
Version 1.94.0:
|
||||||
|
|
||||||
|
API users, please adjust now to planned API changes in 2.0:
|
||||||
|
- EnrollStart will throw an error if the finger was enrolled already
|
||||||
|
- Interactive DBus authentication will only happen when requested
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
- Implement suspend/resume handling.
|
||||||
|
This requires writing "power/persist" and "power/wakeup" in sysfs.
|
||||||
|
- Support libfprint overheat protections
|
||||||
|
- Delete host prints when device prints disappeared
|
||||||
|
- pam: Immediately return success information
|
||||||
|
- Plenty of updated translations thanks to move to Fedora Weblate
|
||||||
|
- Fix possible race when retrieving session information
|
||||||
|
- Fix possible race when a client disconnects
|
||||||
|
- GLib 2.56 compatibility fixes
|
||||||
|
|
||||||
|
|
||||||
Version 1.92.0:
|
Version 1.92.0:
|
||||||
|
|
||||||
API users, please adjust now to planned API changes in 2.0:
|
API users, please adjust now to planned API changes in 2.0:
|
||||||
|
|||||||
7
README
7
README
@ -12,6 +12,13 @@ Licensed under the GPL version 2 or any later version (see COPYING).
|
|||||||
|
|
||||||
A PAM login module is included in the 'pam' directory.
|
A PAM login module is included in the 'pam' directory.
|
||||||
|
|
||||||
|
Translating
|
||||||
|
===========
|
||||||
|
|
||||||
|
fprintd and pam_fprintd are translated using weblate. Please visit
|
||||||
|
https://translate.fedoraproject.org/projects/fprintd/ to contribute
|
||||||
|
translations.
|
||||||
|
|
||||||
API use cases
|
API use cases
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
Updating translations
|
|
||||||
=====================
|
|
||||||
|
|
||||||
The update-transifex.sh script should be run regularly to both pull
|
|
||||||
translations from the Transifex service, and push new strings to translate.
|
|
||||||
|
|
||||||
Transifex.net Token Verification
|
|
||||||
================================
|
|
||||||
|
|
||||||
The list of tokens below guarantee the respective users to be able to enable
|
|
||||||
submission on components using the following repository url:
|
|
||||||
|
|
||||||
https://gitlab.freedesktop.org/libfprint/fprintd/
|
|
||||||
|
|
||||||
Tokens:
|
|
||||||
|
|
||||||
dKfMSehAGCsQ5gxT4r2DAp9PyEMsKAMp / hadess
|
|
||||||
@ -40,3 +40,7 @@ NoNewPrivileges=true
|
|||||||
ProtectClock=yes
|
ProtectClock=yes
|
||||||
DeviceAllow=char-usb_device rw
|
DeviceAllow=char-usb_device rw
|
||||||
DeviceAllow=char-spi rw
|
DeviceAllow=char-spi rw
|
||||||
|
DeviceAllow=char-hidraw rw
|
||||||
|
|
||||||
|
# Allow tuning USB parameters (wakeup and persist)
|
||||||
|
ReadWritePaths=/sys/devices
|
||||||
|
|||||||
12
meson.build
12
meson.build
@ -1,5 +1,5 @@
|
|||||||
project('fprintd', 'c',
|
project('fprintd', 'c',
|
||||||
version: '1.92.0',
|
version: '1.94.0',
|
||||||
license: 'GPLv2+',
|
license: 'GPLv2+',
|
||||||
default_options: [
|
default_options: [
|
||||||
'buildtype=debugoptimized',
|
'buildtype=debugoptimized',
|
||||||
@ -64,7 +64,15 @@ add_project_arguments(common_cflags, language: 'c')
|
|||||||
host_system = host_machine.system()
|
host_system = host_machine.system()
|
||||||
# NOTE: Bump gdbus-codegen min version once we can depend on 2.64!
|
# NOTE: Bump gdbus-codegen min version once we can depend on 2.64!
|
||||||
glib_min_version = '2.56'
|
glib_min_version = '2.56'
|
||||||
libfprint_min_version = '1.92.0'
|
libfprint_min_version = '1.94.0'
|
||||||
|
|
||||||
|
glib_version_def = 'GLIB_VERSION_@0@_@1@'.format(
|
||||||
|
glib_min_version.split('.')[0], glib_min_version.split('.')[1])
|
||||||
|
common_cflags = cc.get_supported_arguments([
|
||||||
|
'-DGLIB_VERSION_MIN_REQUIRED=' + glib_version_def,
|
||||||
|
'-DGLIB_VERSION_MAX_ALLOWED=' + glib_version_def,
|
||||||
|
])
|
||||||
|
add_project_arguments(common_cflags, language: 'c')
|
||||||
|
|
||||||
fprintd_installdir = get_option('prefix') / get_option('libexecdir')
|
fprintd_installdir = get_option('prefix') / get_option('libexecdir')
|
||||||
fprintd_plugindir = get_option('prefix') / get_option('libdir') / meson.project_name() / 'modules'
|
fprintd_plugindir = get_option('prefix') / get_option('libdir') / meson.project_name() / 'modules'
|
||||||
|
|||||||
@ -536,6 +536,14 @@ do_verify (sd_bus *bus,
|
|||||||
data->timed_out = true;
|
data->timed_out = true;
|
||||||
send_info_msg (data->pamh, _("Verification timed out"));
|
send_info_msg (data->pamh, _("Verification timed out"));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (str_equal (data->result, "verify-no-match"))
|
||||||
|
send_err_msg (data->pamh, _("Failed to match fingerprint"));
|
||||||
|
else if (str_equal (data->result, "verify-match"))
|
||||||
|
/* Simply disconnect from bus if we return PAM_SUCCESS */
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ignore errors from VerifyStop */
|
/* Ignore errors from VerifyStop */
|
||||||
data->verify_started = false;
|
data->verify_started = false;
|
||||||
@ -557,11 +565,7 @@ do_verify (sd_bus *bus,
|
|||||||
{
|
{
|
||||||
if (str_equal (data->result, "verify-no-match"))
|
if (str_equal (data->result, "verify-no-match"))
|
||||||
{
|
{
|
||||||
send_err_msg (data->pamh, _("Failed to match fingerprint"));
|
/* Nothing to do at this point. */
|
||||||
}
|
|
||||||
else if (str_equal (data->result, "verify-match"))
|
|
||||||
{
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else if (str_equal (data->result, "verify-unknown-error"))
|
else if (str_equal (data->result, "verify-unknown-error"))
|
||||||
{
|
{
|
||||||
@ -743,10 +747,16 @@ do_auth (pam_handle_t *pamh, const char *username)
|
|||||||
if (claim_device (pamh, bus, data->dev, username))
|
if (claim_device (pamh, bus, data->dev, username))
|
||||||
{
|
{
|
||||||
int ret = do_verify (bus, data);
|
int ret = do_verify (bus, data);
|
||||||
release_device (pamh, bus, data->dev);
|
|
||||||
|
/* Simply disconnect from bus if we return PAM_SUCCESS */
|
||||||
|
if (ret != PAM_SUCCESS)
|
||||||
|
release_device (pamh, bus, data->dev);
|
||||||
|
|
||||||
|
sd_bus_close (bus);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sd_bus_close (bus);
|
||||||
return PAM_AUTHINFO_UNAVAIL;
|
return PAM_AUTHINFO_UNAVAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
po/ca.po
12
po/ca.po
@ -10,7 +10,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 09:46+0000\n"
|
"PO-Revision-Date: 2021-08-15 14:02+0200\n"
|
||||||
"Last-Translator: Robert Antoni Buj i Gelonch <rbuj@fedoraproject.org>\n"
|
"Last-Translator: Robert Antoni Buj i Gelonch <rbuj@fedoraproject.org>\n"
|
||||||
"Language-Team: Catalan (http://www.transifex.com/freedesktop/fprintd/"
|
"Language-Team: Catalan (http://www.transifex.com/freedesktop/fprintd/"
|
||||||
"language/ca/)\n"
|
"language/ca/)\n"
|
||||||
@ -19,6 +19,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Poedit 2.3\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -263,7 +264,7 @@ msgstr "Passeu el dit un altre cop"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:176 pam/fingerprint-strings.h:204
|
#: pam/fingerprint-strings.h:176 pam/fingerprint-strings.h:204
|
||||||
msgid "Swipe was too short, try again"
|
msgid "Swipe was too short, try again"
|
||||||
msgstr "Lectura incorrecta, torneu-ho a intentar"
|
msgstr "Lectura incorrecta. Torneu-ho a intentar"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:178 pam/fingerprint-strings.h:206
|
#: pam/fingerprint-strings.h:178 pam/fingerprint-strings.h:206
|
||||||
msgid "Your finger was not centered, try swiping your finger again"
|
msgid "Your finger was not centered, try swiping your finger again"
|
||||||
@ -275,13 +276,12 @@ msgstr "Retireu el dit i intenteu passar el dit de nou"
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "S'ha esgotat el temps d'espera de la verificació"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Comprova una empremta"
|
msgstr "L'empremta no coincideix"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Hi ha hagut un error desconegut"
|
||||||
|
|||||||
19
po/fi.po
19
po/fi.po
@ -6,20 +6,22 @@
|
|||||||
# Jiri Grönroos <jiri.gronroos@iki.fi>, 2013,2018
|
# Jiri Grönroos <jiri.gronroos@iki.fi>, 2013,2018
|
||||||
# Kimmo Kujansuu <mrkujansuu@gmail.com>, 2019
|
# Kimmo Kujansuu <mrkujansuu@gmail.com>, 2019
|
||||||
# Ville Skyttä <ville.skytta@iki.fi>, 2011,2016
|
# Ville Skyttä <ville.skytta@iki.fi>, 2011,2016
|
||||||
|
# Jan Kuparinen <copper_fin@hotmail.com>, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2019-04-19 20:32+0000\n"
|
"PO-Revision-Date: 2021-07-23 12:04+0000\n"
|
||||||
"Last-Translator: Kimmo Kujansuu <mrkujansuu@gmail.com>\n"
|
"Last-Translator: Jan Kuparinen <copper_fin@hotmail.com>\n"
|
||||||
"Language-Team: Finnish (http://www.transifex.com/freedesktop/fprintd/"
|
"Language-Team: Finnish <https://translate.fedoraproject.org/projects/fprintd/"
|
||||||
"language/fi/)\n"
|
"fprintd/fi/>\n"
|
||||||
"Language: fi\n"
|
"Language: fi\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
|
"X-Generator: Weblate 4.7.2\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -277,13 +279,12 @@ msgstr "Poista sormi ja yritä pyyhkäistä uudelleen"
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Vahvistus aikakatkaistiin"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Vahvista sormenjälki"
|
msgstr "Sormenjäljen vahvistaminen epäonnistui"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Tapahtui tuntematon virhe"
|
||||||
|
|||||||
70
po/fr.po
70
po/fr.po
@ -3,22 +3,23 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Claude Paroz <claude@2xlibre.net>, 2012
|
# Claude Paroz <claude@2xlibre.net>, 2012, 2021.
|
||||||
# Claude Paroz <claude@2xlibre.net>, 2011
|
# Claude Paroz <claude@2xlibre.net>, 2011, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 09:42+0000\n"
|
"PO-Revision-Date: 2021-07-25 12:04+0000\n"
|
||||||
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
|
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
|
||||||
"Language-Team: French (http://www.transifex.com/freedesktop/fprintd/language/"
|
"Language-Team: French <https://translate.fedoraproject.org/projects/fprintd/"
|
||||||
"fr/)\n"
|
"fprintd/fr/>\n"
|
||||||
"Language: fr\n"
|
"Language: fr\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
|
"X-Generator: Weblate 4.7.2\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -41,18 +42,18 @@ msgstr ""
|
|||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:33
|
#: data/net.reactivated.fprint.device.policy.in:33
|
||||||
msgid "Select a user to enroll"
|
msgid "Select a user to enroll"
|
||||||
msgstr "Choisir un utilisateur pour l'introduction"
|
msgstr "Choisir un utilisateur pour l’introduction"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:34
|
#: data/net.reactivated.fprint.device.policy.in:34
|
||||||
msgid "Privileges are required to enroll new fingerprints for other users."
|
msgid "Privileges are required to enroll new fingerprints for other users."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Des permissions sont nécessaires pour introduire de nouvelles empreintes "
|
"Des permissions sont nécessaires pour introduire de nouvelles empreintes "
|
||||||
"digitales pour d'autres utilisateurs."
|
"digitales pour d’autres utilisateurs."
|
||||||
|
|
||||||
#: src/device.c:690
|
#: src/device.c:690
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Device was not claimed before use"
|
msgid "Device was not claimed before use"
|
||||||
msgstr "Le périphérique n'a pas été réservé avant utilisation"
|
msgstr "Le périphérique n’a pas été réservé avant utilisation"
|
||||||
|
|
||||||
#: src/device.c:699
|
#: src/device.c:699
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -61,7 +62,7 @@ msgstr "Le périphérique est déjà utilisé par un autre utilisateur"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:50
|
#: pam/fingerprint-strings.h:50
|
||||||
msgid "Place your finger on the fingerprint reader"
|
msgid "Place your finger on the fingerprint reader"
|
||||||
msgstr "Placez votre doigt sur le lecteur d'empreintes"
|
msgstr "Placez votre doigt sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:51
|
#: pam/fingerprint-strings.h:51
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -70,7 +71,7 @@ msgstr "Placez votre doigt sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:52
|
#: pam/fingerprint-strings.h:52
|
||||||
msgid "Swipe your finger across the fingerprint reader"
|
msgid "Swipe your finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre doigt sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre doigt sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:53
|
#: pam/fingerprint-strings.h:53
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -79,7 +80,7 @@ msgstr "Faites glisser votre doigt sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:55
|
#: pam/fingerprint-strings.h:55
|
||||||
msgid "Place your left thumb on the fingerprint reader"
|
msgid "Place your left thumb on the fingerprint reader"
|
||||||
msgstr "Placez votre pouce gauche sur le lecteur d'empreintes"
|
msgstr "Placez votre pouce gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:56
|
#: pam/fingerprint-strings.h:56
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -88,7 +89,7 @@ msgstr "Placez votre pouce gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:57
|
#: pam/fingerprint-strings.h:57
|
||||||
msgid "Swipe your left thumb across the fingerprint reader"
|
msgid "Swipe your left thumb across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre pouce gauche sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre pouce gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:58
|
#: pam/fingerprint-strings.h:58
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -97,7 +98,7 @@ msgstr "Faites glisser votre pouce gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:60
|
#: pam/fingerprint-strings.h:60
|
||||||
msgid "Place your left index finger on the fingerprint reader"
|
msgid "Place your left index finger on the fingerprint reader"
|
||||||
msgstr "Placez votre index gauche sur le lecteur d'empreintes"
|
msgstr "Placez votre index gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:61
|
#: pam/fingerprint-strings.h:61
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -115,7 +116,7 @@ msgstr "Faites glisser votre index gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:65
|
#: pam/fingerprint-strings.h:65
|
||||||
msgid "Place your left middle finger on the fingerprint reader"
|
msgid "Place your left middle finger on the fingerprint reader"
|
||||||
msgstr "Placez votre majeur gauche sur le lecteur d'empreintes"
|
msgstr "Placez votre majeur gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:66
|
#: pam/fingerprint-strings.h:66
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -124,7 +125,7 @@ msgstr "Placez votre majeur gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:67
|
#: pam/fingerprint-strings.h:67
|
||||||
msgid "Swipe your left middle finger across the fingerprint reader"
|
msgid "Swipe your left middle finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre majeur gauche sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre majeur gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:68
|
#: pam/fingerprint-strings.h:68
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -133,7 +134,7 @@ msgstr "Faites glisser votre majeur gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:70
|
#: pam/fingerprint-strings.h:70
|
||||||
msgid "Place your left ring finger on the fingerprint reader"
|
msgid "Place your left ring finger on the fingerprint reader"
|
||||||
msgstr "Placez votre annulaire gauche sur le lecteur d'empreintes"
|
msgstr "Placez votre annulaire gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:71
|
#: pam/fingerprint-strings.h:71
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -142,7 +143,7 @@ msgstr "Placez votre annulaire gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:72
|
#: pam/fingerprint-strings.h:72
|
||||||
msgid "Swipe your left ring finger across the fingerprint reader"
|
msgid "Swipe your left ring finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre annulaire gauche sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre annulaire gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:73
|
#: pam/fingerprint-strings.h:73
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -151,7 +152,7 @@ msgstr "Faites glisser votre annulaire gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:75
|
#: pam/fingerprint-strings.h:75
|
||||||
msgid "Place your left little finger on the fingerprint reader"
|
msgid "Place your left little finger on the fingerprint reader"
|
||||||
msgstr "Placez votre auriculaire gauche sur le lecteur d'empreintes"
|
msgstr "Placez votre auriculaire gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:76
|
#: pam/fingerprint-strings.h:76
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -160,7 +161,7 @@ msgstr "Placez votre auriculaire gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:77
|
#: pam/fingerprint-strings.h:77
|
||||||
msgid "Swipe your left little finger across the fingerprint reader"
|
msgid "Swipe your left little finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre auriculaire gauche sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre auriculaire gauche sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:78
|
#: pam/fingerprint-strings.h:78
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -169,7 +170,7 @@ msgstr "Faites glisser votre auriculaire gauche sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:80
|
#: pam/fingerprint-strings.h:80
|
||||||
msgid "Place your right thumb on the fingerprint reader"
|
msgid "Place your right thumb on the fingerprint reader"
|
||||||
msgstr "Placez votre pouce droit sur le lecteur d'empreintes"
|
msgstr "Placez votre pouce droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:81
|
#: pam/fingerprint-strings.h:81
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -178,7 +179,7 @@ msgstr "Placez votre pouce droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:82
|
#: pam/fingerprint-strings.h:82
|
||||||
msgid "Swipe your right thumb across the fingerprint reader"
|
msgid "Swipe your right thumb across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre pouce droit sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre pouce droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:83
|
#: pam/fingerprint-strings.h:83
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -187,7 +188,7 @@ msgstr "Faites glisser votre pouce droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:85
|
#: pam/fingerprint-strings.h:85
|
||||||
msgid "Place your right index finger on the fingerprint reader"
|
msgid "Place your right index finger on the fingerprint reader"
|
||||||
msgstr "Placez votre index droit sur le lecteur d'empreintes"
|
msgstr "Placez votre index droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:86
|
#: pam/fingerprint-strings.h:86
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -196,7 +197,7 @@ msgstr "Placez votre index droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:87
|
#: pam/fingerprint-strings.h:87
|
||||||
msgid "Swipe your right index finger across the fingerprint reader"
|
msgid "Swipe your right index finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre index droit sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre index droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:88
|
#: pam/fingerprint-strings.h:88
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -205,7 +206,7 @@ msgstr "Faites glisser votre index droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:90
|
#: pam/fingerprint-strings.h:90
|
||||||
msgid "Place your right middle finger on the fingerprint reader"
|
msgid "Place your right middle finger on the fingerprint reader"
|
||||||
msgstr "Placez votre majeur droit sur le lecteur d'empreintes"
|
msgstr "Placez votre majeur droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:91
|
#: pam/fingerprint-strings.h:91
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -214,7 +215,7 @@ msgstr "Placez votre majeur droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:92
|
#: pam/fingerprint-strings.h:92
|
||||||
msgid "Swipe your right middle finger across the fingerprint reader"
|
msgid "Swipe your right middle finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre majeur droit sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre majeur droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:93
|
#: pam/fingerprint-strings.h:93
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -223,7 +224,7 @@ msgstr "Faites glisser votre majeur droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:95
|
#: pam/fingerprint-strings.h:95
|
||||||
msgid "Place your right ring finger on the fingerprint reader"
|
msgid "Place your right ring finger on the fingerprint reader"
|
||||||
msgstr "Placez votre annulaire droit sur le lecteur d'empreintes"
|
msgstr "Placez votre annulaire droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:96
|
#: pam/fingerprint-strings.h:96
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -232,7 +233,7 @@ msgstr "Placez votre annulaire droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:97
|
#: pam/fingerprint-strings.h:97
|
||||||
msgid "Swipe your right ring finger across the fingerprint reader"
|
msgid "Swipe your right ring finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre annulaire droit sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre annulaire droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:98
|
#: pam/fingerprint-strings.h:98
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -241,7 +242,7 @@ msgstr "Faites glisser votre annulaire droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:100
|
#: pam/fingerprint-strings.h:100
|
||||||
msgid "Place your right little finger on the fingerprint reader"
|
msgid "Place your right little finger on the fingerprint reader"
|
||||||
msgstr "Placez votre auriculaire droit sur le lecteur d'empreintes"
|
msgstr "Placez votre auriculaire droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:101
|
#: pam/fingerprint-strings.h:101
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -250,7 +251,7 @@ msgstr "Placez votre auriculaire droit sur %s"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:102
|
#: pam/fingerprint-strings.h:102
|
||||||
msgid "Swipe your right little finger across the fingerprint reader"
|
msgid "Swipe your right little finger across the fingerprint reader"
|
||||||
msgstr "Faites glisser votre auriculaire droit sur le lecteur d'empreintes"
|
msgstr "Faites glisser votre auriculaire droit sur le lecteur d’empreintes"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:103
|
#: pam/fingerprint-strings.h:103
|
||||||
#, c-format
|
#, c-format
|
||||||
@ -271,8 +272,7 @@ msgstr "Le glissement était trop bref, essayez une nouvelle fois"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:178 pam/fingerprint-strings.h:206
|
#: pam/fingerprint-strings.h:178 pam/fingerprint-strings.h:206
|
||||||
msgid "Your finger was not centered, try swiping your finger again"
|
msgid "Your finger was not centered, try swiping your finger again"
|
||||||
msgstr ""
|
msgstr "Votre doigt n’était pas centré, essayez de le glisser une nouvelle fois"
|
||||||
"Votre doigt n'était pas centré, essayez de le glisser une nouvelle fois"
|
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:180 pam/fingerprint-strings.h:208
|
#: pam/fingerprint-strings.h:180 pam/fingerprint-strings.h:208
|
||||||
msgid "Remove your finger, and try swiping your finger again"
|
msgid "Remove your finger, and try swiping your finger again"
|
||||||
@ -281,12 +281,12 @@ msgstr ""
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Le délai de vérification a expiré"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Echec de reconnaissance de l'empreinte digitale"
|
msgstr "Échec de reconnaissance de l’empreinte digitale"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Une erreur inconnue est survenue"
|
||||||
|
|||||||
16
po/id.po
16
po/id.po
@ -3,21 +3,22 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Andika Triwidada <andika@gmail.com>, 2012
|
# Andika Triwidada <andika@gmail.com>, 2012, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 09:08+0000\n"
|
"PO-Revision-Date: 2021-08-17 02:04+0000\n"
|
||||||
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
|
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
|
||||||
"Language-Team: Indonesian (http://www.transifex.com/freedesktop/fprintd/"
|
"Language-Team: Indonesian <https://translate.fedoraproject.org/projects/"
|
||||||
"language/id/)\n"
|
"fprintd/fprintd/id/>\n"
|
||||||
"Language: id\n"
|
"Language: id\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
|
"X-Generator: Weblate 4.7.2\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -274,13 +275,12 @@ msgstr "Angkat jari Anda, lalu coba gesekkan lagi"
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Verifikasi habis waktu"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Periksa kebenaran sidik jari"
|
msgstr "Gagal mencocokkan sidik jari"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Terjadi kesalahan yang tidak dikenal"
|
||||||
|
|||||||
17
po/ko.po
17
po/ko.po
@ -9,20 +9,22 @@
|
|||||||
# Shinjo Park <kde@peremen.name>, 2015
|
# Shinjo Park <kde@peremen.name>, 2015
|
||||||
# Seong-ho Cho <darkcircle.0426@gmail.com>, 2011,2013
|
# Seong-ho Cho <darkcircle.0426@gmail.com>, 2011,2013
|
||||||
# Shinjo Park <kde@peremen.name>, 2015
|
# Shinjo Park <kde@peremen.name>, 2015
|
||||||
|
# simmon <simmon@nplob.com>, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 09:46+0000\n"
|
"PO-Revision-Date: 2021-07-16 20:04+0000\n"
|
||||||
"Last-Translator: Shinjo Park <kde@peremen.name>\n"
|
"Last-Translator: simmon <simmon@nplob.com>\n"
|
||||||
"Language-Team: Korean (http://www.transifex.com/freedesktop/fprintd/language/"
|
"Language-Team: Korean <https://translate.fedoraproject.org/projects/fprintd/"
|
||||||
"ko/)\n"
|
"fprintd/ko/>\n"
|
||||||
"Language: ko\n"
|
"Language: ko\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
|
"X-Generator: Weblate 4.7.1\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -279,13 +281,12 @@ msgstr "손가락을 뗀 다음 인식기에 다시 문질러 보십시오"
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "인증 시간 초과"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "지문 검증"
|
msgstr "지문과 일치하지 않습니다"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "알 수 없는 오류가 발생했습니다"
|
||||||
|
|||||||
16
po/pl.po
16
po/pl.po
@ -3,16 +3,16 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Piotr Drąg <piotrdrag@gmail.com>, 2012,2016
|
# Piotr Drąg <piotrdrag@gmail.com>, 2012,2016, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 09:08+0000\n"
|
"PO-Revision-Date: 2021-07-24 11:08+0000\n"
|
||||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||||
"Language-Team: Polish (http://www.transifex.com/freedesktop/fprintd/language/"
|
"Language-Team: Polish <https://translate.fedoraproject.org/projects/fprintd/"
|
||||||
"pl/)\n"
|
"fprintd/pl/>\n"
|
||||||
"Language: pl\n"
|
"Language: pl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@ -20,6 +20,7 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n"
|
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n"
|
||||||
"%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n"
|
"%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n"
|
||||||
"%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
"%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
||||||
|
"X-Generator: Weblate 4.7.2\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -278,13 +279,12 @@ msgstr ""
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Weryfikacja przekroczyła czas oczekiwania"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Weryfikowanie odcisków palców"
|
msgstr "Dopasowanie odcisku palca się nie powiodło"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Wystąpił nieznany błąd"
|
||||||
|
|||||||
21
po/pt_BR.po
21
po/pt_BR.po
@ -4,20 +4,22 @@
|
|||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Rafael Fontenelle <rffontenelle@gmail.com>, 2012
|
# Rafael Fontenelle <rffontenelle@gmail.com>, 2012
|
||||||
|
# Rafael Fontenelle <rafaelff@gnome.org>, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 11:53+0000\n"
|
"PO-Revision-Date: 2021-07-16 20:04+0000\n"
|
||||||
"Last-Translator: Rafael Fontenelle <rffontenelle@gmail.com>\n"
|
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
|
||||||
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/freedesktop/"
|
"Language-Team: Portuguese (Brazil) <https://translate.fedoraproject.org/"
|
||||||
"fprintd/language/pt_BR/)\n"
|
"projects/fprintd/fprintd/pt_BR/>\n"
|
||||||
"Language: pt_BR\n"
|
"Language: pt_BR\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
|
"X-Generator: Weblate 4.7.1\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -271,17 +273,16 @@ msgstr "Seu dedo não estava no centro, tente pressioná-lo novamente"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:180 pam/fingerprint-strings.h:208
|
#: pam/fingerprint-strings.h:180 pam/fingerprint-strings.h:208
|
||||||
msgid "Remove your finger, and try swiping your finger again"
|
msgid "Remove your finger, and try swiping your finger again"
|
||||||
msgstr "Remova seu dedo e tente pressioná-lo novamente."
|
msgstr "Remova seu dedo e tente pressioná-lo novamente"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Verificação expirou"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Verificar uma impressão digital"
|
msgstr "Falha ao corresponder a impressão digital"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Ocorreu um erro desconhecido"
|
||||||
|
|||||||
19
po/sv.po
19
po/sv.po
@ -3,20 +3,22 @@
|
|||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
|
# Anders Jonsson <anders.jonsson@norsjovallen.se>, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 09:08+0000\n"
|
"PO-Revision-Date: 2021-07-16 20:04+0000\n"
|
||||||
"Last-Translator: Anders Jonsson <transifex@norsjovallen.se>\n"
|
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
|
||||||
"Language-Team: Swedish (http://www.transifex.com/freedesktop/fprintd/"
|
"Language-Team: Swedish <https://translate.fedoraproject.org/projects/fprintd/"
|
||||||
"language/sv/)\n"
|
"fprintd/sv/>\n"
|
||||||
"Language: sv\n"
|
"Language: sv\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
|
"X-Generator: Weblate 4.7.1\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -273,13 +275,12 @@ msgstr "Ta bort ditt finger och prova att dra ditt finger igen"
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Tidsgräns för verifiering överskreds"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Verifiera fingeravtryck"
|
msgstr "Misslyckades med att matcha fingeravtryck"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Ett okänt fel inträffade"
|
||||||
|
|||||||
35
po/tr.po
35
po/tr.po
@ -5,20 +5,22 @@
|
|||||||
# Translators:
|
# Translators:
|
||||||
# Caner Başaran <basaran.caner@gmail.com>, 2014
|
# Caner Başaran <basaran.caner@gmail.com>, 2014
|
||||||
# Emin Tufan Çetin <etcetin@gmail.com>, 2020
|
# Emin Tufan Çetin <etcetin@gmail.com>, 2020
|
||||||
|
# Oğuz Ersen <oguzersen@protonmail.com>, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2020-02-29 10:08+0000\n"
|
"PO-Revision-Date: 2021-07-16 20:04+0000\n"
|
||||||
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
|
"Last-Translator: Oğuz Ersen <oguzersen@protonmail.com>\n"
|
||||||
"Language-Team: Turkish (http://www.transifex.com/freedesktop/fprintd/"
|
"Language-Team: Turkish <https://translate.fedoraproject.org/projects/fprintd/"
|
||||||
"language/tr/)\n"
|
"fprintd/tr/>\n"
|
||||||
"Language: tr\n"
|
"Language: tr\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n>1);\n"
|
||||||
|
"X-Generator: Weblate 4.7.1\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -147,21 +149,21 @@ msgstr "Sol yüzük parmağınızı %s üzerinde kaydırın"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:75
|
#: pam/fingerprint-strings.h:75
|
||||||
msgid "Place your left little finger on the fingerprint reader"
|
msgid "Place your left little finger on the fingerprint reader"
|
||||||
msgstr "Sol küçük parmağınızı parmak izi okuyucuya yerleştirin"
|
msgstr "Sol serçe parmağınızı parmak izi okuyucuya yerleştirin"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:76
|
#: pam/fingerprint-strings.h:76
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Place your left little finger on %s"
|
msgid "Place your left little finger on %s"
|
||||||
msgstr "Sol küçük parmağınızı %s üzerine yerleştirin"
|
msgstr "Sol serçe parmağınızı %s üzerine yerleştirin"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:77
|
#: pam/fingerprint-strings.h:77
|
||||||
msgid "Swipe your left little finger across the fingerprint reader"
|
msgid "Swipe your left little finger across the fingerprint reader"
|
||||||
msgstr "Sol küçük parmağınızı parmak izi okuyucu üzerinde kaydırın"
|
msgstr "Sol serçe parmağınızı parmak izi okuyucu üzerinde kaydırın"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:78
|
#: pam/fingerprint-strings.h:78
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Swipe your left little finger across %s"
|
msgid "Swipe your left little finger across %s"
|
||||||
msgstr "Sol küçük parmağınızı %s üzerinde kaydırın"
|
msgstr "Sol serçe parmağınızı %s üzerinde kaydırın"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:80
|
#: pam/fingerprint-strings.h:80
|
||||||
msgid "Place your right thumb on the fingerprint reader"
|
msgid "Place your right thumb on the fingerprint reader"
|
||||||
@ -237,21 +239,21 @@ msgstr "Sağ yüzük parmağınızı %s üzerinde kaydırın"
|
|||||||
|
|
||||||
#: pam/fingerprint-strings.h:100
|
#: pam/fingerprint-strings.h:100
|
||||||
msgid "Place your right little finger on the fingerprint reader"
|
msgid "Place your right little finger on the fingerprint reader"
|
||||||
msgstr "Sağ küçük parmağınızı parmak izi okuyucuya yerleştirin"
|
msgstr "Sağ serçe parmağınızı parmak izi okuyucuya yerleştirin"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:101
|
#: pam/fingerprint-strings.h:101
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Place your right little finger on %s"
|
msgid "Place your right little finger on %s"
|
||||||
msgstr "Sağ küçük parmağınızı %s üzerine yerleştirin"
|
msgstr "Sağ serçe parmağınızı %s üzerine yerleştirin"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:102
|
#: pam/fingerprint-strings.h:102
|
||||||
msgid "Swipe your right little finger across the fingerprint reader"
|
msgid "Swipe your right little finger across the fingerprint reader"
|
||||||
msgstr "Sağ küçük parmağınızı parmak izi okuyucu üzerinde kaydırın"
|
msgstr "Sağ serçe parmağınızı parmak izi okuyucu üzerinde kaydırın"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:103
|
#: pam/fingerprint-strings.h:103
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Swipe your right little finger across %s"
|
msgid "Swipe your right little finger across %s"
|
||||||
msgstr "Sağ küçük parmağınızı %s üzerinde kaydırın"
|
msgstr "Sağ serçe parmağınızı %s üzerinde kaydırın"
|
||||||
|
|
||||||
#: pam/fingerprint-strings.h:171 pam/fingerprint-strings.h:199
|
#: pam/fingerprint-strings.h:171 pam/fingerprint-strings.h:199
|
||||||
msgid "Place your finger on the reader again"
|
msgid "Place your finger on the reader again"
|
||||||
@ -275,13 +277,12 @@ msgstr "Parmağınızı kaldırın ve yeniden kaydırmayı deneyin"
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Doğrulama zaman aşımına uğradı"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Parmak izini doğrula"
|
msgstr "Parmak izi eşleştirilemedi"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Bilinmeyen bir hata oluştu"
|
||||||
|
|||||||
24
po/uk.po
24
po/uk.po
@ -4,24 +4,25 @@
|
|||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Richard Hughes <richard@hughsie.com>, 2011
|
# Richard Hughes <richard@hughsie.com>, 2011
|
||||||
# Yuri Chornoivan <yurchor@ukr.net>, 2009, 2010, 2011, 2012
|
# Yuri Chornoivan <yurchor@ukr.net>, 2009, 2010, 2011, 2012, 2021.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: fprintd\n"
|
"Project-Id-Version: fprintd\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
"POT-Creation-Date: 2021-06-30 14:00+0200\n"
|
||||||
"PO-Revision-Date: 2017-09-19 09:08+0000\n"
|
"PO-Revision-Date: 2021-07-16 20:04+0000\n"
|
||||||
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
|
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
|
||||||
"Language-Team: Ukrainian (http://www.transifex.com/freedesktop/fprintd/"
|
"Language-Team: Ukrainian <https://translate.fedoraproject.org/projects/"
|
||||||
"language/uk/)\n"
|
"fprintd/fprintd/uk/>\n"
|
||||||
"Language: uk\n"
|
"Language: uk\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != "
|
"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 "
|
||||||
"11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % "
|
"? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > "
|
||||||
"100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || "
|
"14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % "
|
||||||
"(n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n"
|
"100 >=11 && n % 100 <=14 )) ? 2: 3);\n"
|
||||||
|
"X-Generator: Weblate 4.7.1\n"
|
||||||
|
|
||||||
#: data/net.reactivated.fprint.device.policy.in:13
|
#: data/net.reactivated.fprint.device.policy.in:13
|
||||||
msgid "Verify a fingerprint"
|
msgid "Verify a fingerprint"
|
||||||
@ -283,13 +284,12 @@ msgstr "Приберіть ваш палець і повторіть спроб
|
|||||||
|
|
||||||
#: pam/pam_fprintd.c:537
|
#: pam/pam_fprintd.c:537
|
||||||
msgid "Verification timed out"
|
msgid "Verification timed out"
|
||||||
msgstr ""
|
msgstr "Перевищено час перевірки"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:560
|
#: pam/pam_fprintd.c:560
|
||||||
#, fuzzy
|
|
||||||
msgid "Failed to match fingerprint"
|
msgid "Failed to match fingerprint"
|
||||||
msgstr "Перевірити відбиток"
|
msgstr "Не вдалося встановити відповідність відбитка"
|
||||||
|
|
||||||
#: pam/pam_fprintd.c:576
|
#: pam/pam_fprintd.c:576
|
||||||
msgid "An unknown error occurred"
|
msgid "An unknown error occurred"
|
||||||
msgstr ""
|
msgstr "Сталася невідома помилка"
|
||||||
|
|||||||
228
src/device.c
228
src/device.c
@ -101,6 +101,8 @@ typedef struct
|
|||||||
FpDevice *dev;
|
FpDevice *dev;
|
||||||
SessionData *_session;
|
SessionData *_session;
|
||||||
|
|
||||||
|
gboolean local_storage_checked;
|
||||||
|
|
||||||
guint verify_stop_wait_timeout_id;
|
guint verify_stop_wait_timeout_id;
|
||||||
|
|
||||||
PolkitAuthority *auth;
|
PolkitAuthority *auth;
|
||||||
@ -127,7 +129,7 @@ G_DEFINE_TYPE_WITH_CODE (FprintDevice, fprint_device,
|
|||||||
|
|
||||||
enum fprint_device_properties {
|
enum fprint_device_properties {
|
||||||
FPRINT_DEVICE_CONSTRUCT_DEV = 1,
|
FPRINT_DEVICE_CONSTRUCT_DEV = 1,
|
||||||
FPRINT_DEVICE_IN_USE,
|
FPRINT_DEVICE_BUSY,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum fprint_device_signals {
|
enum fprint_device_signals {
|
||||||
@ -168,7 +170,7 @@ session_data_get (FprintDevicePrivate *priv)
|
|||||||
/* Get the current pointer and mark the pointer as "busy". */
|
/* Get the current pointer and mark the pointer as "busy". */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
cur = priv->_session;
|
cur = g_atomic_pointer_get (&priv->_session);
|
||||||
/* Swap if cur is valid, otherwise busy loop. */
|
/* Swap if cur is valid, otherwise busy loop. */
|
||||||
}
|
}
|
||||||
while (cur == invalid || !g_atomic_pointer_compare_and_exchange (&priv->_session, cur, invalid));
|
while (cur == invalid || !g_atomic_pointer_compare_and_exchange (&priv->_session, cur, invalid));
|
||||||
@ -205,7 +207,7 @@ session_data_set_new (FprintDevicePrivate *priv, gchar *sender, gchar *username)
|
|||||||
/* Get the current (but not if it is busy) and put the new one in place. */
|
/* Get the current (but not if it is busy) and put the new one in place. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
old = priv->_session;
|
old = g_atomic_pointer_get (&priv->_session);
|
||||||
/* Swap if old is valid, otherwise busy loop as someone is ref'ing it currently. */
|
/* Swap if old is valid, otherwise busy loop as someone is ref'ing it currently. */
|
||||||
}
|
}
|
||||||
while (old == invalid || !g_atomic_pointer_compare_and_exchange (&priv->_session, old, new));
|
while (old == invalid || !g_atomic_pointer_compare_and_exchange (&priv->_session, old, new));
|
||||||
@ -293,8 +295,10 @@ fprint_device_get_property (GObject *object, guint property_id,
|
|||||||
g_value_set_object (value, priv->dev);
|
g_value_set_object (value, priv->dev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FPRINT_DEVICE_IN_USE:
|
case FPRINT_DEVICE_BUSY:
|
||||||
g_value_set_boolean (value, g_hash_table_size (priv->clients) != 0);
|
g_value_set_boolean (value,
|
||||||
|
g_hash_table_size (priv->clients) != 0 ||
|
||||||
|
fp_device_get_temperature (priv->dev) > FP_TEMPERATURE_COLD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -359,6 +363,14 @@ on_finger_status_changed (FprintDevice *rdev,
|
|||||||
g_debug ("Finger needed %d", needed);
|
g_debug ("Finger needed %d", needed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_temperature_changed (FprintDevice *rdev,
|
||||||
|
GParamSpec *spec,
|
||||||
|
FpDevice *device)
|
||||||
|
{
|
||||||
|
g_object_notify (G_OBJECT (rdev), "busy");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fprint_device_constructed (GObject *object)
|
fprint_device_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
@ -383,6 +395,11 @@ fprint_device_constructed (GObject *object)
|
|||||||
rdev, G_CONNECT_SWAPPED);
|
rdev, G_CONNECT_SWAPPED);
|
||||||
on_finger_status_changed (rdev, NULL, priv->dev);
|
on_finger_status_changed (rdev, NULL, priv->dev);
|
||||||
|
|
||||||
|
g_signal_connect_object (priv->dev, "notify::temperature",
|
||||||
|
G_CALLBACK (on_temperature_changed),
|
||||||
|
rdev, G_CONNECT_SWAPPED);
|
||||||
|
on_temperature_changed (rdev, NULL, priv->dev);
|
||||||
|
|
||||||
G_OBJECT_CLASS (fprint_device_parent_class)->constructed (object);
|
G_OBJECT_CLASS (fprint_device_parent_class)->constructed (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,11 +422,11 @@ fprint_device_class_init (FprintDeviceClass *klass)
|
|||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
FPRINT_DEVICE_CONSTRUCT_DEV, pspec);
|
FPRINT_DEVICE_CONSTRUCT_DEV, pspec);
|
||||||
|
|
||||||
pspec = g_param_spec_boolean ("in-use", "In use",
|
pspec = g_param_spec_boolean ("busy", "Busy",
|
||||||
"Whether the device is currently in use", FALSE,
|
"Whether the device is in use or too warm", FALSE,
|
||||||
G_PARAM_READABLE);
|
G_PARAM_READABLE);
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
FPRINT_DEVICE_IN_USE, pspec);
|
FPRINT_DEVICE_BUSY, pspec);
|
||||||
|
|
||||||
signals[SIGNAL_VERIFY_STATUS] =
|
signals[SIGNAL_VERIFY_STATUS] =
|
||||||
g_signal_lookup ("verify-status", FPRINT_TYPE_DEVICE);
|
g_signal_lookup ("verify-status", FPRINT_TYPE_DEVICE);
|
||||||
@ -460,6 +477,81 @@ _fprint_device_get_id (FprintDevice *rdev)
|
|||||||
return priv->id;
|
return priv->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
suspend_cb (GObject *source_obj,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GTask) task = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
fp_device_suspend_finish (FP_DEVICE (source_obj), res, &error);
|
||||||
|
if (error)
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resume_cb (GObject *source_obj,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GTask) task = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
fp_device_resume_finish (FP_DEVICE (source_obj), res, &error);
|
||||||
|
if (error)
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
else
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fprint_device_suspend (FprintDevice *rdev,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
GTask *task = NULL;
|
||||||
|
FprintDevicePrivate *priv = fprint_device_get_instance_private (rdev);
|
||||||
|
|
||||||
|
/* Just forward to libfprint. */
|
||||||
|
|
||||||
|
task = g_task_new (rdev, NULL, callback, user_data);
|
||||||
|
fp_device_suspend (priv->dev, NULL, suspend_cb, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fprint_device_resume (FprintDevice *rdev,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
GTask *task = NULL;
|
||||||
|
FprintDevicePrivate *priv = fprint_device_get_instance_private (rdev);
|
||||||
|
|
||||||
|
/* Just forward to libfprint. */
|
||||||
|
|
||||||
|
task = g_task_new (rdev, NULL, callback, user_data);
|
||||||
|
fp_device_resume (priv->dev, NULL, resume_cb, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fprint_device_suspend_finish (FprintDevice *rdev,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fprint_device_resume_finish (FprintDevice *rdev,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
fp_finger_to_name (FpFinger finger)
|
fp_finger_to_name (FpFinger finger)
|
||||||
{
|
{
|
||||||
@ -521,7 +613,8 @@ verify_result_to_name (gboolean match, GError *error)
|
|||||||
*/
|
*/
|
||||||
if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO))
|
if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_PROTO))
|
||||||
return "verify-disconnected";
|
return "verify-disconnected";
|
||||||
else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
|
||||||
|
g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_NOT_FOUND))
|
||||||
return "verify-no-match";
|
return "verify-no-match";
|
||||||
|
|
||||||
return "verify-unknown-error";
|
return "verify-unknown-error";
|
||||||
@ -891,7 +984,7 @@ _fprint_device_client_vanished (GDBusConnection *connection,
|
|||||||
g_hash_table_remove (priv->clients, name);
|
g_hash_table_remove (priv->clients, name);
|
||||||
|
|
||||||
if (g_hash_table_size (priv->clients) == 0)
|
if (g_hash_table_size (priv->clients) == 0)
|
||||||
g_object_notify (G_OBJECT (rdev), "in-use");
|
g_object_notify (G_OBJECT (rdev), "busy");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -911,7 +1004,7 @@ _fprint_device_add_client (FprintDevice *rdev, const char *sender)
|
|||||||
rdev,
|
rdev,
|
||||||
NULL);
|
NULL);
|
||||||
g_hash_table_insert (priv->clients, g_strdup (sender), GUINT_TO_POINTER (id));
|
g_hash_table_insert (priv->clients, g_strdup (sender), GUINT_TO_POINTER (id));
|
||||||
g_object_notify (G_OBJECT (rdev), "in-use");
|
g_object_notify (G_OBJECT (rdev), "busy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1081,6 +1174,14 @@ fprint_device_release (FprintDBusDevice *dbus_dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
session = session_data_get (priv);
|
session = session_data_get (priv);
|
||||||
|
|
||||||
|
/* We iterated the mainloop, the session may have disappeared already. */
|
||||||
|
if (!session)
|
||||||
|
{
|
||||||
|
fprint_dbus_device_complete_release (FPRINT_DBUS_DEVICE (rdev), invocation);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
session->invocation = g_object_ref (invocation);
|
session->invocation = g_object_ref (invocation);
|
||||||
|
|
||||||
priv->current_action = ACTION_CLOSE;
|
priv->current_action = ACTION_CLOSE;
|
||||||
@ -1124,6 +1225,7 @@ load_all_prints (FprintDevice *rdev)
|
|||||||
{
|
{
|
||||||
g_autoptr(GPtrArray) res = g_ptr_array_new_with_free_func (g_object_unref);
|
g_autoptr(GPtrArray) res = g_ptr_array_new_with_free_func (g_object_unref);
|
||||||
GSList *user, *users = NULL;
|
GSList *user, *users = NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
users = store.discover_users ();
|
users = store.discover_users ();
|
||||||
|
|
||||||
@ -1132,7 +1234,9 @@ load_all_prints (FprintDevice *rdev)
|
|||||||
const char *username = user->data;
|
const char *username = user->data;
|
||||||
g_autoptr(GPtrArray) prints = load_user_prints (rdev, username);
|
g_autoptr(GPtrArray) prints = load_user_prints (rdev, username);
|
||||||
|
|
||||||
g_ptr_array_extend_and_steal (res, g_steal_pointer (&prints));
|
/* TODO: Use g_ptr_array_extend_and_steal with GLib >= 2.62 */
|
||||||
|
for (i = 0; i < prints->len; i++)
|
||||||
|
g_ptr_array_add (res, g_object_ref (g_ptr_array_index (prints, i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free_full (users, g_free);
|
g_slist_free_full (users, g_free);
|
||||||
@ -1171,6 +1275,93 @@ report_verify_status (FprintDevice *rdev,
|
|||||||
session->verify_status_reported = TRUE;
|
session->verify_status_reported = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_local_storage (FprintDevice *rdev,
|
||||||
|
gboolean found_match,
|
||||||
|
GError *error)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) err = NULL;
|
||||||
|
g_autoptr(GPtrArray) device_prints = NULL;
|
||||||
|
g_autoptr(GPtrArray) host_prints = NULL;
|
||||||
|
FprintDevicePrivate *priv = fprint_device_get_instance_private (rdev);
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
g_return_if_fail (priv->current_action == ACTION_VERIFY ||
|
||||||
|
priv->current_action == ACTION_IDENTIFY);
|
||||||
|
|
||||||
|
/* This only ever sense if the device can list prints. */
|
||||||
|
if (!fp_device_has_feature (priv->dev, FP_DEVICE_FEATURE_STORAGE_LIST))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* We do not have any proper driver that correctly reports DATA_NOT_FOUND
|
||||||
|
* errors. Only synaptics, but there the feature is being disabled on the
|
||||||
|
* firmware side.
|
||||||
|
* As such, just always run a test the first time we get a match failure.
|
||||||
|
*/
|
||||||
|
if (g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_NOT_FOUND))
|
||||||
|
{
|
||||||
|
if (priv->local_storage_checked)
|
||||||
|
g_warning ("Device %s reported that a passed print did not exist during action %d, but we verified the local storage!",
|
||||||
|
fp_device_get_name (priv->dev), priv->current_action);
|
||||||
|
else
|
||||||
|
g_debug ("Device %s reported that a passed print did not exist during action %d",
|
||||||
|
fp_device_get_name (priv->dev), priv->current_action);
|
||||||
|
}
|
||||||
|
else if (error || priv->local_storage_checked)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!found_match)
|
||||||
|
{
|
||||||
|
g_debug ("Device %s failed to match during action %d, verifying local storage",
|
||||||
|
fp_device_get_name (priv->dev), priv->current_action);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->local_storage_checked = TRUE;
|
||||||
|
|
||||||
|
device_prints = fp_device_list_prints_sync (priv->dev, NULL, &err);
|
||||||
|
if (!device_prints)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to query prints: %s", err->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
host_prints = load_all_prints (rdev);
|
||||||
|
|
||||||
|
for (i = 0; i < host_prints->len; i++)
|
||||||
|
{
|
||||||
|
FpPrint *print = g_ptr_array_index (host_prints, i);
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (g_ptr_array_find_with_equal_func (device_prints,
|
||||||
|
print,
|
||||||
|
(GEqualFunc) fp_print_equal,
|
||||||
|
NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Print not known by device, remove locally */
|
||||||
|
if ((r = store.print_data_delete (priv->dev,
|
||||||
|
fp_print_get_finger (print),
|
||||||
|
fp_print_get_username (print))) == 0)
|
||||||
|
{
|
||||||
|
g_message ("Deleted stored finger %d for user %s as it is unknown to device.",
|
||||||
|
fp_print_get_finger (print),
|
||||||
|
fp_print_get_username (print));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Error deleting finger %d for user %s that is unknown to device: %d!",
|
||||||
|
fp_print_get_finger (print),
|
||||||
|
fp_print_get_username (print),
|
||||||
|
r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
can_start_action (FprintDevice *rdev, GError **error)
|
can_start_action (FprintDevice *rdev, GError **error)
|
||||||
{
|
{
|
||||||
@ -1345,8 +1536,6 @@ match_cb (FpDevice *device,
|
|||||||
cancelled = g_cancellable_is_cancelled (priv->current_cancellable);
|
cancelled = g_cancellable_is_cancelled (priv->current_cancellable);
|
||||||
matched = match != NULL && cancelled == FALSE;
|
matched = match != NULL && cancelled == FALSE;
|
||||||
|
|
||||||
/* No-match is reported only after the operation completes.
|
|
||||||
* This avoids problems when the operation is immediately restarted. */
|
|
||||||
report_verify_status (rdev, matched, error);
|
report_verify_status (rdev, matched, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1389,6 +1578,8 @@ verify_cb (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
error->message);
|
error->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_local_storage (rdev, match, error);
|
||||||
|
|
||||||
stoppable_action_completed (rdev);
|
stoppable_action_completed (rdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1432,6 +1623,8 @@ identify_cb (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
error->message);
|
error->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_local_storage (rdev, match != NULL, error);
|
||||||
|
|
||||||
stoppable_action_completed (rdev);
|
stoppable_action_completed (rdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1506,7 +1699,9 @@ fprint_device_verify_start (FprintDBusDevice *dbus_dev,
|
|||||||
|
|
||||||
if (gallery)
|
if (gallery)
|
||||||
{
|
{
|
||||||
print = g_ptr_array_steal_index_fast (gallery, 0);
|
/* TODO: Use g_ptr_array_remove_index_fast with GLib >= 2.58 */
|
||||||
|
print = g_object_ref (g_ptr_array_index (gallery, 0));
|
||||||
|
g_ptr_array_remove_index_fast (gallery, 0);
|
||||||
finger = fp_print_get_finger (print);
|
finger = fp_print_get_finger (print);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1931,7 +2126,8 @@ enroll_identify_cb (FpDevice *dev, GAsyncResult *res, void *user_data)
|
|||||||
priv->current_cancellable,
|
priv->current_cancellable,
|
||||||
&error))
|
&error))
|
||||||
{
|
{
|
||||||
g_warning ("Failed to garbage collect duplicate print, cannot continue with enroll.");
|
g_warning ("Failed to garbage collect duplicate print, cannot continue with enroll: %s",
|
||||||
|
error->message);
|
||||||
g_signal_emit (rdev, signals[SIGNAL_ENROLL_STATUS], 0, "enroll-duplicate", TRUE);
|
g_signal_emit (rdev, signals[SIGNAL_ENROLL_STATUS], 0, "enroll-duplicate", TRUE);
|
||||||
|
|
||||||
stoppable_action_completed (rdev);
|
stoppable_action_completed (rdev);
|
||||||
|
|||||||
@ -220,6 +220,14 @@ file_storage_print_data_load (FpDevice *dev,
|
|||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
/* Make sure the username/finger matches our expectations. */
|
||||||
|
if (fp_print_get_finger (new) != finger)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (g_strcmp0 (fp_print_get_username (new), username) != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* And that the print is compatible with the device. */
|
||||||
if (!fp_print_compatible (new, dev))
|
if (!fp_print_compatible (new, dev))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,22 @@ struct _FprintDevice
|
|||||||
|
|
||||||
FprintDevice *fprint_device_new (FpDevice *dev);
|
FprintDevice *fprint_device_new (FpDevice *dev);
|
||||||
guint32 _fprint_device_get_id (FprintDevice *rdev);
|
guint32 _fprint_device_get_id (FprintDevice *rdev);
|
||||||
|
|
||||||
|
void fprint_device_suspend (FprintDevice *rdev,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
void *user_data);
|
||||||
|
void fprint_device_resume (FprintDevice *rdev,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
void fprint_device_suspend_finish (FprintDevice *rdev,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error);
|
||||||
|
void fprint_device_resume_finish (FprintDevice *rdev,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
|
||||||
/* Print */
|
/* Print */
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
|
||||||
|
|||||||
196
src/manager.c
196
src/manager.c
@ -24,9 +24,14 @@
|
|||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <fprint.h>
|
#include <fprint.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <gio/gunixfdlist.h>
|
||||||
|
|
||||||
#include "fprintd.h"
|
#include "fprintd.h"
|
||||||
|
|
||||||
|
#define LOGIND_BUS_NAME "org.freedesktop.login1"
|
||||||
|
#define LOGIND_IFACE_NAME "org.freedesktop.login1.Manager"
|
||||||
|
#define LOGIND_OBJ_PATH "/org/freedesktop/login1"
|
||||||
|
|
||||||
static void fprint_manager_constructed (GObject *object);
|
static void fprint_manager_constructed (GObject *object);
|
||||||
static gboolean fprint_manager_get_devices (FprintManager *manager,
|
static gboolean fprint_manager_get_devices (FprintManager *manager,
|
||||||
GPtrArray **devices,
|
GPtrArray **devices,
|
||||||
@ -43,6 +48,9 @@ typedef struct
|
|||||||
FpContext *context;
|
FpContext *context;
|
||||||
gboolean no_timeout;
|
gboolean no_timeout;
|
||||||
guint timeout_id;
|
guint timeout_id;
|
||||||
|
gint prepare_for_sleep_pending;
|
||||||
|
guint prepare_for_sleep_id;
|
||||||
|
gint sleep_inhibit_fd;
|
||||||
} FprintManagerPrivate;
|
} FprintManagerPrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (FprintManager, fprint_manager, G_TYPE_OBJECT, G_ADD_PRIVATE (FprintManager))
|
G_DEFINE_TYPE_WITH_CODE (FprintManager, fprint_manager, G_TYPE_OBJECT, G_ADD_PRIVATE (FprintManager))
|
||||||
@ -60,6 +68,10 @@ fprint_manager_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
FprintManagerPrivate *priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object));
|
FprintManagerPrivate *priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object));
|
||||||
|
|
||||||
|
if (priv->prepare_for_sleep_id)
|
||||||
|
g_dbus_connection_signal_unsubscribe (priv->connection,
|
||||||
|
priv->prepare_for_sleep_id);
|
||||||
|
|
||||||
g_clear_object (&priv->object_manager);
|
g_clear_object (&priv->object_manager);
|
||||||
g_clear_object (&priv->dbus_manager);
|
g_clear_object (&priv->dbus_manager);
|
||||||
g_clear_object (&priv->connection);
|
g_clear_object (&priv->connection);
|
||||||
@ -152,14 +164,14 @@ fprint_manager_timeout_cb (FprintManager *manager)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fprint_manager_in_use_notified (FprintDevice *rdev, GParamSpec *spec, FprintManager *manager)
|
fprint_manager_busy_notified (FprintDevice *rdev, GParamSpec *spec, FprintManager *manager)
|
||||||
{
|
{
|
||||||
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
|
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
|
||||||
guint num_devices_used = 0;
|
guint num_devices_busy = 0;
|
||||||
|
|
||||||
g_autolist (GDBusObject) devices = NULL;
|
g_autolist (GDBusObject) devices = NULL;
|
||||||
GList *l;
|
GList *l;
|
||||||
gboolean in_use;
|
gboolean busy;
|
||||||
|
|
||||||
if (priv->timeout_id > 0)
|
if (priv->timeout_id > 0)
|
||||||
{
|
{
|
||||||
@ -177,12 +189,12 @@ fprint_manager_in_use_notified (FprintDevice *rdev, GParamSpec *spec, FprintMana
|
|||||||
FprintDBusObjectSkeleton *object = l->data;
|
FprintDBusObjectSkeleton *object = l->data;
|
||||||
|
|
||||||
dev = fprint_dbus_object_skeleton_get_device (object);
|
dev = fprint_dbus_object_skeleton_get_device (object);
|
||||||
g_object_get (G_OBJECT (dev), "in-use", &in_use, NULL);
|
g_object_get (G_OBJECT (dev), "busy", &busy, NULL);
|
||||||
if (in_use != FALSE)
|
if (busy != FALSE)
|
||||||
num_devices_used++;
|
num_devices_busy++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_devices_used == 0)
|
if (num_devices_busy == 0)
|
||||||
priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager);
|
priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +239,153 @@ handle_get_default_device (FprintManager *manager,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fprint_device_suspend_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
FprintManager *manager = FPRINT_MANAGER (user_data);
|
||||||
|
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
|
||||||
|
|
||||||
|
/* Fetch the result (except for the NULL dummy call). */
|
||||||
|
if (source_object != NULL)
|
||||||
|
{
|
||||||
|
fprint_device_suspend_finish (FPRINT_DEVICE (source_object), res, &error);
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
if (!g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_OPEN) &&
|
||||||
|
!g_error_matches (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED))
|
||||||
|
g_message ("Unexpected error while suspending device: %s", error->message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->prepare_for_sleep_pending -= 1;
|
||||||
|
|
||||||
|
/* Close FD when all devices are prepared for sleeping. */
|
||||||
|
if (priv->prepare_for_sleep_pending == 0)
|
||||||
|
{
|
||||||
|
if (priv->sleep_inhibit_fd >= 0)
|
||||||
|
close (priv->sleep_inhibit_fd);
|
||||||
|
priv->sleep_inhibit_fd = -1;
|
||||||
|
g_debug ("Released delay inhibitor for sleep.");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
logind_sleep_inhibit_cb (GObject *source_object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr(GVariant) data = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(GUnixFDList) out_fd_list = NULL;
|
||||||
|
g_autoptr(FprintManager) manager = FPRINT_MANAGER (user_data);
|
||||||
|
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
|
||||||
|
gint fd_offset;
|
||||||
|
|
||||||
|
data = g_dbus_connection_call_with_unix_fd_list_finish (priv->connection, &out_fd_list, res, &error);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to install a sleep delay inhibitor: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->sleep_inhibit_fd >= 0)
|
||||||
|
close (priv->sleep_inhibit_fd);
|
||||||
|
|
||||||
|
g_debug ("Got delay inhibitor for sleep.");
|
||||||
|
|
||||||
|
g_variant_get (data, "(h)", &fd_offset);
|
||||||
|
priv->sleep_inhibit_fd = g_unix_fd_list_get (out_fd_list, fd_offset, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_prepare_for_sleep_signal (GDBusConnection *connection,
|
||||||
|
const gchar *sender_name,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *signal_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autolist (GDBusObject) devices = NULL;
|
||||||
|
FprintManager *manager = FPRINT_MANAGER (user_data);
|
||||||
|
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
|
||||||
|
gboolean prepare_for_sleep;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
if (!g_variant_check_format_string (parameters, "(b)", FALSE))
|
||||||
|
{
|
||||||
|
g_warning ("Received incorrect parameter for PrepareForSleep signal");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_get (parameters, "(b)", &prepare_for_sleep);
|
||||||
|
|
||||||
|
/* called one more time to handle the case of no devices */
|
||||||
|
if (prepare_for_sleep)
|
||||||
|
priv->prepare_for_sleep_pending = 1;
|
||||||
|
|
||||||
|
devices = g_dbus_object_manager_get_objects (priv->object_manager);
|
||||||
|
|
||||||
|
g_debug ("Preparing devices for %s", prepare_for_sleep ? "sleep" : "resume");
|
||||||
|
|
||||||
|
for (l = devices; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
g_autoptr(FprintDevice) dev = NULL;
|
||||||
|
FprintDBusObjectSkeleton *object = l->data;
|
||||||
|
|
||||||
|
dev = fprint_dbus_object_skeleton_get_device (object);
|
||||||
|
|
||||||
|
if (prepare_for_sleep)
|
||||||
|
{
|
||||||
|
priv->prepare_for_sleep_pending += 1;
|
||||||
|
g_object_ref (manager);
|
||||||
|
fprint_device_suspend (dev, fprint_device_suspend_cb, manager);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprint_device_resume (dev, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prepare_for_sleep)
|
||||||
|
{
|
||||||
|
/* "Notify" the initial dummy device we added, handling no devices that suspending */
|
||||||
|
g_object_ref (manager);
|
||||||
|
fprint_device_suspend_cb (NULL, NULL, manager);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GVariant *arg = NULL;
|
||||||
|
|
||||||
|
arg = g_variant_new ("(ssss)",
|
||||||
|
"sleep",
|
||||||
|
"net.reactivated.Fprint",
|
||||||
|
"Suspend fingerprint readers",
|
||||||
|
"delay");
|
||||||
|
|
||||||
|
/* Grab a sleep inhibitor. */
|
||||||
|
g_dbus_connection_call_with_unix_fd_list (priv->connection,
|
||||||
|
LOGIND_BUS_NAME,
|
||||||
|
LOGIND_OBJ_PATH,
|
||||||
|
LOGIND_IFACE_NAME,
|
||||||
|
"Inhibit",
|
||||||
|
arg,
|
||||||
|
G_VARIANT_TYPE ("(h)"),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
logind_sleep_inhibit_cb,
|
||||||
|
g_object_ref (manager));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
device_added_cb (FprintManager *manager, FpDevice *device, FpContext *context)
|
device_added_cb (FprintManager *manager, FpDevice *device, FpContext *context)
|
||||||
{
|
{
|
||||||
@ -238,8 +397,8 @@ device_added_cb (FprintManager *manager, FpDevice *device, FpContext *context)
|
|||||||
|
|
||||||
rdev = fprint_device_new (device);
|
rdev = fprint_device_new (device);
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (rdev), "notify::in-use",
|
g_signal_connect (G_OBJECT (rdev), "notify::busy",
|
||||||
G_CALLBACK (fprint_manager_in_use_notified), manager);
|
G_CALLBACK (fprint_manager_busy_notified), manager);
|
||||||
|
|
||||||
path = get_device_path (rdev);
|
path = get_device_path (rdev);
|
||||||
|
|
||||||
@ -282,14 +441,15 @@ device_removed_cb (FprintManager *manager, FpDevice *device, FpContext *context)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The device that disappeared might have been in-use.
|
/* The device that disappeared might have been busy.
|
||||||
* Do we need to do anything else in this case to clean up more gracefully? */
|
* Do we need to do anything else in this case to clean up more gracefully? */
|
||||||
fprint_manager_in_use_notified (NULL, NULL, manager);
|
fprint_manager_busy_notified (NULL, NULL, manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fprint_manager_constructed (GObject *object)
|
fprint_manager_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
|
g_autoptr(GVariant) param_false = NULL;
|
||||||
FprintManager *manager = FPRINT_MANAGER (object);
|
FprintManager *manager = FPRINT_MANAGER (object);
|
||||||
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
|
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
|
||||||
GDBusObjectManagerServer *object_manager_server;
|
GDBusObjectManagerServer *object_manager_server;
|
||||||
@ -319,6 +479,20 @@ fprint_manager_constructed (GObject *object)
|
|||||||
g_dbus_object_manager_server_set_connection (object_manager_server,
|
g_dbus_object_manager_server_set_connection (object_manager_server,
|
||||||
priv->connection);
|
priv->connection);
|
||||||
|
|
||||||
|
priv->prepare_for_sleep_id = g_dbus_connection_signal_subscribe (priv->connection,
|
||||||
|
LOGIND_BUS_NAME,
|
||||||
|
LOGIND_IFACE_NAME,
|
||||||
|
"PrepareForSleep",
|
||||||
|
LOGIND_OBJ_PATH,
|
||||||
|
NULL,
|
||||||
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||||
|
handle_prepare_for_sleep_signal,
|
||||||
|
manager,
|
||||||
|
NULL);
|
||||||
|
/* Fake a resume as that triggers the inhibitor to be taken. */
|
||||||
|
param_false = g_variant_new ("(b)", FALSE);
|
||||||
|
handle_prepare_for_sleep_signal (priv->connection, NULL, NULL, NULL, NULL, param_false, manager);
|
||||||
|
|
||||||
/* And register the signals for initial enumeration and hotplug. */
|
/* And register the signals for initial enumeration and hotplug. */
|
||||||
g_signal_connect_object (priv->context,
|
g_signal_connect_object (priv->context,
|
||||||
"device-added",
|
"device-added",
|
||||||
|
|||||||
182
tests/fprintd.py
182
tests/fprintd.py
@ -38,6 +38,7 @@ gi.require_version('FPrint', '2.0')
|
|||||||
from gi.repository import GLib, Gio, FPrint
|
from gi.repository import GLib, Gio, FPrint
|
||||||
from output_checker import OutputChecker
|
from output_checker import OutputChecker
|
||||||
import cairo
|
import cairo
|
||||||
|
import signal
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from subprocess import DEVNULL
|
from subprocess import DEVNULL
|
||||||
@ -120,6 +121,8 @@ class Connection:
|
|||||||
self.con.close()
|
self.con.close()
|
||||||
del self.con
|
del self.con
|
||||||
|
|
||||||
|
# Speed up tests by only loading a 128x128px area from the center
|
||||||
|
MAX_IMG_SIZE = 128
|
||||||
def load_image(img):
|
def load_image(img):
|
||||||
png = cairo.ImageSurface.create_from_png(img)
|
png = cairo.ImageSurface.create_from_png(img)
|
||||||
|
|
||||||
@ -128,7 +131,13 @@ def load_image(img):
|
|||||||
h = png.get_height()
|
h = png.get_height()
|
||||||
w = (w + 3) // 4 * 4
|
w = (w + 3) // 4 * 4
|
||||||
h = (h + 3) // 4 * 4
|
h = (h + 3) // 4 * 4
|
||||||
img = cairo.ImageSurface(cairo.Format.A8, w, h)
|
|
||||||
|
w_out = min(MAX_IMG_SIZE, w)
|
||||||
|
h_out = min(MAX_IMG_SIZE, h)
|
||||||
|
x = (w - w_out) // 2
|
||||||
|
y = (h - h_out) // 2
|
||||||
|
|
||||||
|
img = cairo.ImageSurface(cairo.Format.A8, w_out, h_out)
|
||||||
cr = cairo.Context(img)
|
cr = cairo.Context(img)
|
||||||
|
|
||||||
cr.set_source_rgba(1, 1, 1, 1)
|
cr.set_source_rgba(1, 1, 1, 1)
|
||||||
@ -137,7 +146,7 @@ def load_image(img):
|
|||||||
cr.set_source_rgba(0, 0, 0, 0)
|
cr.set_source_rgba(0, 0, 0, 0)
|
||||||
cr.set_operator(cairo.OPERATOR_SOURCE)
|
cr.set_operator(cairo.OPERATOR_SOURCE)
|
||||||
|
|
||||||
cr.set_source_surface(png)
|
cr.set_source_surface(png, -x, -y)
|
||||||
cr.paint()
|
cr.paint()
|
||||||
|
|
||||||
return img
|
return img
|
||||||
@ -164,6 +173,11 @@ class FPrintdTest(dbusmock.DBusTestCase):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
# Try to generate backtrace if meson kills as with SIGTERM
|
||||||
|
def r(*args):
|
||||||
|
raise KeyboardInterrupt()
|
||||||
|
signal.signal(signal.SIGTERM, r)
|
||||||
|
|
||||||
super().setUpClass()
|
super().setUpClass()
|
||||||
fprintd = None
|
fprintd = None
|
||||||
cls._polkitd = None
|
cls._polkitd = None
|
||||||
@ -233,10 +247,15 @@ class FPrintdTest(dbusmock.DBusTestCase):
|
|||||||
argv.insert(2, '--suppressions=%s' % valgrind)
|
argv.insert(2, '--suppressions=%s' % valgrind)
|
||||||
self.valgrind = True
|
self.valgrind = True
|
||||||
self.kill_daemon = False
|
self.kill_daemon = False
|
||||||
|
self.daemon_log = OutputChecker()
|
||||||
self.daemon = subprocess.Popen(argv,
|
self.daemon = subprocess.Popen(argv,
|
||||||
env=env,
|
env=env,
|
||||||
stdout=None,
|
stdout=self.daemon_log.fd,
|
||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
|
self.daemon_log.writer_attached()
|
||||||
|
|
||||||
|
#subprocess.Popen(['/usr/bin/dbus-monitor', '--system'])
|
||||||
|
|
||||||
self.addCleanup(self.daemon_stop)
|
self.addCleanup(self.daemon_stop)
|
||||||
|
|
||||||
timeout_count = timeout * 10
|
timeout_count = timeout * 10
|
||||||
@ -296,6 +315,8 @@ class FPrintdTest(dbusmock.DBusTestCase):
|
|||||||
else:
|
else:
|
||||||
raise(e)
|
raise(e)
|
||||||
|
|
||||||
|
self.daemon_log.assert_closed()
|
||||||
|
|
||||||
if not self.kill_daemon:
|
if not self.kill_daemon:
|
||||||
self.assertLess(self.daemon.returncode, 128)
|
self.assertLess(self.daemon.returncode, 128)
|
||||||
self.assertGreaterEqual(self.daemon.returncode, 0)
|
self.assertGreaterEqual(self.daemon.returncode, 0)
|
||||||
@ -577,8 +598,22 @@ class FPrintdVirtualDeviceBaseTest(FPrintdVirtualImageDeviceBaseTests):
|
|||||||
self.manager = None
|
self.manager = None
|
||||||
self.device = None
|
self.device = None
|
||||||
self.polkitd_start()
|
self.polkitd_start()
|
||||||
|
|
||||||
|
fifo_path = os.path.join(self.tmpdir, 'logind_inhibit_fifo')
|
||||||
|
os.mkfifo(fifo_path)
|
||||||
|
self.logind_inhibit_fifo = os.open(fifo_path, os.O_RDONLY | os.O_NONBLOCK | os.O_CLOEXEC)
|
||||||
|
# EOF without a writer, BlockingIOError with a writer
|
||||||
|
self.assertFalse(self.holds_inhibitor())
|
||||||
|
|
||||||
|
self.logind, self.logind_obj = self.spawn_server_template('logind', { })
|
||||||
|
self.logind_obj.AddMethod('org.freedesktop.login1.Manager', 'Inhibit', 'ssss', 'h',
|
||||||
|
'ret = os.open("%s", os.O_WRONLY)\n' % fifo_path +
|
||||||
|
'from gi.repository import GLib\n' +
|
||||||
|
'GLib.idle_add(lambda fd: os.close(fd), ret)')
|
||||||
self.daemon_start(self.driver_name)
|
self.daemon_start(self.driver_name)
|
||||||
|
|
||||||
|
self.wait_got_delay_inhibitor()
|
||||||
|
|
||||||
if self.device is None:
|
if self.device is None:
|
||||||
self.skipTest("Need {} device to run the test".format(self.device_driver))
|
self.skipTest("Need {} device to run the test".format(self.device_driver))
|
||||||
|
|
||||||
@ -627,6 +662,8 @@ class FPrintdVirtualDeviceBaseTest(FPrintdVirtualImageDeviceBaseTests):
|
|||||||
self.device = None
|
self.device = None
|
||||||
self.manager = None
|
self.manager = None
|
||||||
|
|
||||||
|
os.close(self.logind_inhibit_fifo)
|
||||||
|
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
|
||||||
def try_release(self):
|
def try_release(self):
|
||||||
@ -658,6 +695,23 @@ class FPrintdVirtualDeviceBaseTest(FPrintdVirtualImageDeviceBaseTests):
|
|||||||
if expected is not None:
|
if expected is not None:
|
||||||
self.assertEqual(self._last_result, expected)
|
self.assertEqual(self._last_result, expected)
|
||||||
|
|
||||||
|
def holds_inhibitor(self):
|
||||||
|
try:
|
||||||
|
if os.read(self.logind_inhibit_fifo, 1) == b'':
|
||||||
|
return False
|
||||||
|
except BlockingIOError:
|
||||||
|
return True
|
||||||
|
|
||||||
|
raise AssertionError("logind inhibitor fifo in unexpected state")
|
||||||
|
|
||||||
|
def wait_got_delay_inhibitor(self, timeout=0):
|
||||||
|
self.daemon_log.check_line('Got delay inhibitor for sleep', timeout=timeout)
|
||||||
|
self.assertTrue(self.holds_inhibitor())
|
||||||
|
|
||||||
|
def wait_released_delay_inhibitor(self, timeout=0):
|
||||||
|
self.daemon_log.check_line('Released delay inhibitor for sleep', timeout=timeout)
|
||||||
|
self.assertFalse(self.holds_inhibitor())
|
||||||
|
|
||||||
def enroll_image(self, img, device=None, finger='right-index-finger',
|
def enroll_image(self, img, device=None, finger='right-index-finger',
|
||||||
expected_result='enroll-completed', claim_user=None,
|
expected_result='enroll-completed', claim_user=None,
|
||||||
start=True, stop=True):
|
start=True, stop=True):
|
||||||
@ -1032,6 +1086,51 @@ class FPrintdVirtualStorageDeviceTests(FPrintdVirtualStorageDeviceBaseTest):
|
|||||||
prints = self.get_stored_prints()
|
prints = self.get_stored_prints()
|
||||||
self.assertEqual(set(prints), set(garbage_prints))
|
self.assertEqual(set(prints), set(garbage_prints))
|
||||||
|
|
||||||
|
def test_local_storage_cleanup_data_error(self):
|
||||||
|
# Enroll a print and delete it
|
||||||
|
self.enroll_print('deleted-print', finger='left-thumb')
|
||||||
|
self.send_command('REMOVE', 'deleted-print')
|
||||||
|
|
||||||
|
# Note: would be thrown anyway by the storage device if we scan something
|
||||||
|
self.send_error(FPrint.DeviceError.DATA_NOT_FOUND)
|
||||||
|
self.device.VerifyStart('(s)', 'any')
|
||||||
|
|
||||||
|
self.wait_for_result('verify-no-match')
|
||||||
|
self.device.VerifyStop()
|
||||||
|
|
||||||
|
# At this point, there is no print left
|
||||||
|
with self.assertFprintError('NoEnrolledPrints'):
|
||||||
|
self.device.ListEnrolledFingers('(s)', 'testuser')
|
||||||
|
|
||||||
|
def test_local_storage_cleanup_no_match(self):
|
||||||
|
# Enroll a print and delete it
|
||||||
|
self.enroll_print('existing-print', finger='right-index-finger')
|
||||||
|
self.enroll_print('deleted-print', finger='left-thumb')
|
||||||
|
self.send_command('REMOVE', 'deleted-print')
|
||||||
|
|
||||||
|
# We need to send a print that is known to the device
|
||||||
|
self.send_image('other-print')
|
||||||
|
self.device.VerifyStart('(s)', 'right-index-finger')
|
||||||
|
|
||||||
|
self.wait_for_result('verify-no-match')
|
||||||
|
self.device.VerifyStop()
|
||||||
|
|
||||||
|
# At this point, the deleted print has disappeared
|
||||||
|
self.assertEqual(set(self.device.ListEnrolledFingers('(s)', 'testuser')), {'right-index-finger'})
|
||||||
|
|
||||||
|
# Now, do the same thing, and the print will not be deleted
|
||||||
|
self.enroll_print('deleted-print', finger='left-thumb')
|
||||||
|
self.send_command('REMOVE', 'deleted-print')
|
||||||
|
|
||||||
|
self.send_image('other-print')
|
||||||
|
self.device.VerifyStart('(s)', 'right-index-finger')
|
||||||
|
|
||||||
|
self.wait_for_result('verify-no-match')
|
||||||
|
self.device.VerifyStop()
|
||||||
|
|
||||||
|
# At this point, the deleted print is still there
|
||||||
|
self.assertEqual(set(self.device.ListEnrolledFingers('(s)', 'testuser')), {'right-index-finger', 'left-thumb'})
|
||||||
|
|
||||||
def test_enroll_with_one_stage_only(self):
|
def test_enroll_with_one_stage_only(self):
|
||||||
self._maybe_reduce_enroll_stages(stages=1)
|
self._maybe_reduce_enroll_stages(stages=1)
|
||||||
|
|
||||||
@ -1524,6 +1623,72 @@ class FPrintdVirtualDeviceTest(FPrintdVirtualDeviceBaseTest):
|
|||||||
|
|
||||||
self.assertIn(GLib.Variant('()', ()), self.get_all_async_replies())
|
self.assertIn(GLib.Variant('()', ()), self.get_all_async_replies())
|
||||||
|
|
||||||
|
def test_suspend_inhibit_unclaimed(self):
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [True])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for sleep', timeout=1)
|
||||||
|
self.wait_released_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [False])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for resume', timeout=1)
|
||||||
|
self.wait_got_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
def test_suspend_inhibit_claimed(self):
|
||||||
|
self.device.Claim('(s)', 'testuser')
|
||||||
|
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [True])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for sleep', timeout=1)
|
||||||
|
self.wait_released_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [False])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for resume', timeout=1)
|
||||||
|
self.wait_got_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
self.device.Release()
|
||||||
|
|
||||||
|
def test_suspend_inhibit_cancels_enroll(self):
|
||||||
|
self.device.Claim('(s)', 'testuser')
|
||||||
|
|
||||||
|
self.device.EnrollStart('(s)', 'right-thumb')
|
||||||
|
|
||||||
|
# Now prepare for sleep, which will trigger an internal cancellation
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [True])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for sleep', timeout=1)
|
||||||
|
self.wait_for_result(expected='enroll-unknown-error')
|
||||||
|
self.wait_released_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
self.assertEqual(os.read(self.logind_inhibit_fifo, 1), b'')
|
||||||
|
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [False])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for resume', timeout=1)
|
||||||
|
self.wait_got_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
self.device.Release()
|
||||||
|
|
||||||
|
def test_suspend_prevents_enroll(self):
|
||||||
|
self.device.Claim('(s)', 'testuser')
|
||||||
|
|
||||||
|
# Now prepare for sleep, which will trigger an internal cancellation
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [True])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for sleep', timeout=1)
|
||||||
|
self.wait_released_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
self.device.EnrollStart('(s)', 'right-thumb')
|
||||||
|
self.wait_for_result(expected='enroll-unknown-error')
|
||||||
|
|
||||||
|
self.logind_obj.EmitSignal("", "PrepareForSleep", "b", [False])
|
||||||
|
|
||||||
|
self.daemon_log.check_line('Preparing devices for resume', timeout=1)
|
||||||
|
self.wait_got_delay_inhibitor(timeout=1)
|
||||||
|
|
||||||
|
self.device.Release()
|
||||||
|
|
||||||
|
|
||||||
class FPrintdVirtualDeviceStorageTest(FPrintdVirtualStorageDeviceBaseTest,
|
class FPrintdVirtualDeviceStorageTest(FPrintdVirtualStorageDeviceBaseTest,
|
||||||
FPrintdVirtualDeviceTest):
|
FPrintdVirtualDeviceTest):
|
||||||
@ -2580,7 +2745,7 @@ class FPrintdVirtualDeviceVerificationTests(FPrintdVirtualDeviceBaseTest):
|
|||||||
self.assertVerifyError(FPrint.DeviceError.DATA_INVALID, 'verify-unknown-error')
|
self.assertVerifyError(FPrint.DeviceError.DATA_INVALID, 'verify-unknown-error')
|
||||||
|
|
||||||
def test_verify_error_data_not_found(self):
|
def test_verify_error_data_not_found(self):
|
||||||
self.assertVerifyError(FPrint.DeviceError.DATA_NOT_FOUND, 'verify-unknown-error')
|
self.assertVerifyError(FPrint.DeviceError.DATA_NOT_FOUND, 'verify-no-match')
|
||||||
|
|
||||||
def test_verify_error_data_full(self):
|
def test_verify_error_data_full(self):
|
||||||
self.assertVerifyError(FPrint.DeviceError.DATA_FULL, 'verify-unknown-error')
|
self.assertVerifyError(FPrint.DeviceError.DATA_FULL, 'verify-unknown-error')
|
||||||
@ -2665,15 +2830,6 @@ class FPrintdVirtualDeviceVerificationTests(FPrintdVirtualDeviceBaseTest):
|
|||||||
self.assertIsNone(self._last_result)
|
self.assertIsNone(self._last_result)
|
||||||
self.assertFalse(self.finger_present)
|
self.assertFalse(self.finger_present)
|
||||||
|
|
||||||
def test_verify_stop_restarts_immediately(self):
|
|
||||||
self.send_image('tented_arch')
|
|
||||||
self.assertVerifyNoMatch()
|
|
||||||
|
|
||||||
self.call_device_method_async('VerifyStop', '()', [])
|
|
||||||
self.call_device_method_async('VerifyStart', '(s)', [self.verify_finger])
|
|
||||||
|
|
||||||
self.wait_for_device_reply(expected_replies=2)
|
|
||||||
|
|
||||||
def test_verify_stop_waits_for_completion(self):
|
def test_verify_stop_waits_for_completion(self):
|
||||||
self.stop_on_teardown = False
|
self.stop_on_teardown = False
|
||||||
|
|
||||||
|
|||||||
@ -43,25 +43,34 @@ class OutputChecker(object):
|
|||||||
fcntl.fcntl(self._pipe_fd_w, fcntl.F_GETFL) | os.O_CLOEXEC)
|
fcntl.fcntl(self._pipe_fd_w, fcntl.F_GETFL) | os.O_CLOEXEC)
|
||||||
|
|
||||||
# Start copier thread
|
# Start copier thread
|
||||||
self._thread = threading.Thread(target=self._copy)
|
self._thread = threading.Thread(target=self._copy, daemon=True)
|
||||||
self._thread.start()
|
self._thread.start()
|
||||||
|
|
||||||
def _copy(self):
|
def _copy(self):
|
||||||
|
p = select.poll()
|
||||||
|
p.register(self._pipe_fd_r)
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
# Be lazy and wake up occasionally in case _pipe_fd_r became invalid
|
# Be lazy and wake up occasionally in case _pipe_fd_r became invalid
|
||||||
# The reason to do this is because os.read() will *not* return if the
|
# The reason to do this is because os.read() will *not* return if the
|
||||||
# FD is forcefully closed.
|
# FD is forcefully closed.
|
||||||
select.select([self._pipe_fd_r], [], [], 0.1)
|
p.poll(0.1)
|
||||||
|
|
||||||
r = os.read(self._pipe_fd_r, 1024)
|
r = os.read(self._pipe_fd_r, 1024)
|
||||||
if not r:
|
if not r:
|
||||||
|
os.close(self._pipe_fd_r)
|
||||||
|
self._pipe_fd_r = -1
|
||||||
|
self._lines_sem.release()
|
||||||
return
|
return
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == errno.EWOULDBLOCK:
|
if e.errno == errno.EWOULDBLOCK:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# We get a bad file descriptor error when the outside closes the FD
|
# We get a bad file descriptor error when the outside closes the FD
|
||||||
|
if self._pipe_fd_r >= 0:
|
||||||
|
os.close(self._pipe_fd_r)
|
||||||
|
self._pipe_fd_r = -1
|
||||||
|
self._lines_sem.release()
|
||||||
return
|
return
|
||||||
|
|
||||||
l = r.split(b'\n')
|
l = r.split(b'\n')
|
||||||
@ -86,6 +95,13 @@ class OutputChecker(object):
|
|||||||
try:
|
try:
|
||||||
l = self._lines.pop(0)
|
l = self._lines.pop(0)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
# EOF, throw error
|
||||||
|
if self._pipe_fd_r == -1:
|
||||||
|
if failmsg:
|
||||||
|
raise AssertionError("No further messages: " % failmsg)
|
||||||
|
else:
|
||||||
|
raise AssertionError('No client waiting for needle %s' % (str(needle_re)))
|
||||||
|
|
||||||
# Check if should wake up
|
# Check if should wake up
|
||||||
if not self._lines_sem.acquire(timeout = deadline - time.time()):
|
if not self._lines_sem.acquire(timeout = deadline - time.time()):
|
||||||
if failmsg:
|
if failmsg:
|
||||||
@ -119,6 +135,10 @@ class OutputChecker(object):
|
|||||||
try:
|
try:
|
||||||
l = self._lines.pop(0)
|
l = self._lines.pop(0)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
# EOF, so everything good
|
||||||
|
if self._pipe_fd_r == -1:
|
||||||
|
break
|
||||||
|
|
||||||
# Check if should wake up
|
# Check if should wake up
|
||||||
if not self._lines_sem.acquire(timeout = deadline - time.time()):
|
if not self._lines_sem.acquire(timeout = deadline - time.time()):
|
||||||
# Timed out, so everything is good
|
# Timed out, so everything is good
|
||||||
@ -130,7 +150,7 @@ class OutputChecker(object):
|
|||||||
if failmsg:
|
if failmsg:
|
||||||
raise AssertionError(failmsg)
|
raise AssertionError(failmsg)
|
||||||
else:
|
else:
|
||||||
raise AssertionError('Found needle %s but shouldn\'t have been there (timeout: %0.2f)' % (str(needle_re), timeout))
|
raise AssertionError('Found needle %s but shouldn\'t have been there (timeout: %0.2f)' % (str(needle_re), wait))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -157,7 +177,8 @@ class OutputChecker(object):
|
|||||||
|
|
||||||
fd = self._pipe_fd_r
|
fd = self._pipe_fd_r
|
||||||
self._pipe_fd_r = -1
|
self._pipe_fd_r = -1
|
||||||
os.close(fd)
|
if fd >= 0:
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
self._thread.join()
|
self._thread.join()
|
||||||
|
|
||||||
@ -170,9 +191,9 @@ class OutputChecker(object):
|
|||||||
self._pipe_fd_w = -1
|
self._pipe_fd_w = -1
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self._pipe_fd_r > 0:
|
if self._pipe_fd_r >= 0:
|
||||||
os.close(self._pipe_fd_r)
|
os.close(self._pipe_fd_r)
|
||||||
if self._pipe_fd_w > 0:
|
self._pipe_fd_r = -1
|
||||||
|
if self._pipe_fd_w >= 0:
|
||||||
os.close(self._pipe_fd_w)
|
os.close(self._pipe_fd_w)
|
||||||
|
self._pipe_fd_w = -1
|
||||||
assert not self._thread.is_alive()
|
|
||||||
|
|||||||
@ -143,6 +143,12 @@ class TestPamFprintd(dbusmock.DBusTestCase):
|
|||||||
self.assertRegex(res.info[0], r'Swipe your left little finger across the fingerprint reader')
|
self.assertRegex(res.info[0], r'Swipe your left little finger across the fingerprint reader')
|
||||||
self.assertEqual(len(res.errors), 0)
|
self.assertEqual(len(res.errors), 0)
|
||||||
|
|
||||||
|
# Check that we can stop verification and release the device. i.e.
|
||||||
|
# this has not been done by PAM already (the real fprintd would notice
|
||||||
|
# the disconnect, the mock service does not).
|
||||||
|
self.device_mock.VerifyStop()
|
||||||
|
self.device_mock.Release()
|
||||||
|
|
||||||
def test_pam_fprintd_no_fingers(self):
|
def test_pam_fprintd_no_fingers(self):
|
||||||
self.setup_device()
|
self.setup_device()
|
||||||
self.device_mock.SetEnrolledFingers('toto', dbus.Array(set([]), signature='s'))
|
self.device_mock.SetEnrolledFingers('toto', dbus.Array(set([]), signature='s'))
|
||||||
@ -199,6 +205,13 @@ class TestPamFprintd(dbusmock.DBusTestCase):
|
|||||||
self.assertRegex(res.errors[0], r'Failed to match fingerprint')
|
self.assertRegex(res.errors[0], r'Failed to match fingerprint')
|
||||||
self.assertRegex(res.errors[0], r'Failed to match fingerprint')
|
self.assertRegex(res.errors[0], r'Failed to match fingerprint')
|
||||||
|
|
||||||
|
# Check that we can cannot stop verification or release the device. i.e.
|
||||||
|
# PAM should have correctly done this after verification was done.
|
||||||
|
with self.assertRaisesRegex(dbus.exceptions.DBusException, r'net\.reactivated\.Fprint\.Error\.NoActionInProgress'):
|
||||||
|
self.device_mock.VerifyStop()
|
||||||
|
with self.assertRaisesRegex(dbus.exceptions.DBusException, r'net\.reactivated\.Fprint\.Error\.ClaimDevice'):
|
||||||
|
self.device_mock.Release()
|
||||||
|
|
||||||
def test_pam_fprintd_blocks_unexpected_auth2(self):
|
def test_pam_fprintd_blocks_unexpected_auth2(self):
|
||||||
self.setup_device()
|
self.setup_device()
|
||||||
script = [
|
script = [
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
test -f .tx/config || exit 1
|
|
||||||
|
|
||||||
echo Pulling translations from Transifex
|
|
||||||
tx --root `dirname $0` pull --all --force --skip
|
|
||||||
|
|
||||||
echo Pushing strings to Transifex
|
|
||||||
tx push --source
|
|
||||||
Reference in New Issue
Block a user