88//! - A fingerprint reader must be connected
99//! - User must have enrolled fingerprints
1010
11- use super :: { UserVerificationProvider , VerificationContext , VerificationError , VerificationResult } ;
11+ use super :: {
12+ UserVerificationProvider , VerificationContext , VerificationError , VerificationResult , priority,
13+ } ;
1214
1315use log:: { debug, error, info, warn} ;
1416
15- use std:: sync:: { Arc , Mutex } ;
17+ use std:: sync:: Arc ;
18+ use std:: sync:: Mutex ;
1619
1720/// fprintd-based fingerprint verification provider
1821pub struct FprintdProvider {
19- available_cache : Arc < Mutex < Option < bool > > > ,
22+ available_cache : Mutex < Option < bool > > ,
23+ runtime : Mutex < Option < Arc < tokio:: runtime:: Runtime > > > ,
2024}
2125
2226impl FprintdProvider {
2327 /// Create a new fprintd provider
2428 pub fn new ( ) -> Self {
2529 Self {
26- available_cache : Arc :: new ( Mutex :: new ( None ) ) ,
30+ available_cache : Mutex :: new ( None ) ,
31+ runtime : Mutex :: new ( None ) ,
2732 }
2833 }
2934
35+ /// Create a provider if enabled in config
36+ pub fn from_config ( enabled : bool ) -> Option < Box < dyn UserVerificationProvider > > {
37+ if enabled {
38+ Some ( Box :: new ( Self :: new ( ) ) )
39+ } else {
40+ None
41+ }
42+ }
43+
44+ /// Get or create the tokio runtime
45+ fn get_runtime ( & self ) -> Result < Arc < tokio:: runtime:: Runtime > , VerificationError > {
46+ let mut runtime_guard = self . runtime . lock ( ) . unwrap ( ) ;
47+ if runtime_guard. is_none ( ) {
48+ * runtime_guard = Some ( Arc :: new ( tokio:: runtime:: Runtime :: new ( ) . map_err ( |e| {
49+ VerificationError :: DeviceError ( format ! ( "Failed to create runtime: {}" , e) )
50+ } ) ?) ) ;
51+ }
52+ Ok ( runtime_guard. as_ref ( ) . unwrap ( ) . clone ( ) )
53+ }
54+
3055 async fn do_verify ( timeout_secs : u32 ) -> Result < VerificationResult , VerificationError > {
3156 use zbus:: Connection ;
3257
@@ -195,8 +220,8 @@ impl FprintdProvider {
195220 Ok ( result)
196221 }
197222
198- fn check_available_sync ( ) -> bool {
199- let rt = match tokio :: runtime :: Runtime :: new ( ) {
223+ fn check_available ( & self ) -> bool {
224+ let rt = match self . get_runtime ( ) {
200225 Ok ( rt) => rt,
201226 Err ( _) => return false ,
202227 } ;
@@ -252,7 +277,7 @@ impl UserVerificationProvider for FprintdProvider {
252277 return cached;
253278 }
254279
255- let available = Self :: check_available_sync ( ) ;
280+ let available = self . check_available ( ) ;
256281 * self . available_cache . lock ( ) . unwrap ( ) = Some ( available) ;
257282 available
258283 }
@@ -262,22 +287,13 @@ impl UserVerificationProvider for FprintdProvider {
262287 context : & VerificationContext ,
263288 ) -> Result < VerificationResult , VerificationError > {
264289 let timeout_secs = context. timeout_seconds ;
290+ let rt = self . get_runtime ( ) ?;
265291
266- let result = std:: thread:: spawn ( move || {
267- let rt = tokio:: runtime:: Runtime :: new ( ) . map_err ( |e| {
268- VerificationError :: DeviceError ( format ! ( "Failed to create runtime: {}" , e) )
269- } ) ?;
270-
271- rt. block_on ( async { Self :: do_verify ( timeout_secs) . await } )
272- } )
273- . join ( )
274- . map_err ( |_| VerificationError :: Other ( "Verification thread panicked" . into ( ) ) ) ??;
275-
276- Ok ( result)
292+ rt. block_on ( async { Self :: do_verify ( timeout_secs) . await } )
277293 }
278294
279295 fn priority ( & self ) -> u8 {
280- 100
296+ priority :: FPRINTD
281297 }
282298
283299 fn supports_enrollment ( & self ) -> bool {
@@ -306,7 +322,7 @@ mod tests {
306322 #[ test]
307323 fn test_fprintd_provider_priority ( ) {
308324 let provider = FprintdProvider :: new ( ) ;
309- assert_eq ! ( provider. priority( ) , 100 ) ;
325+ assert_eq ! ( provider. priority( ) , priority :: FPRINTD ) ;
310326 }
311327
312328 #[ test]
0 commit comments