1+ use crate :: status_update:: send_status;
12use crate :: transport:: hid:: HIDDevice ;
3+ use crate :: StatusUpdate ;
24
35pub use crate :: transport:: platform:: device:: Device ;
46
@@ -45,7 +47,7 @@ pub struct DeviceSelector {
4547}
4648
4749impl DeviceSelector {
48- pub fn run ( ) -> Self {
50+ pub fn run ( status : Sender < crate :: StatusUpdate > ) -> Self {
4951 let ( selector_send, selector_rec) = channel ( ) ;
5052 // let new_device_callback = Arc::new(new_device_cb);
5153 let runloop = RunLoop :: new ( move |alive| {
@@ -77,6 +79,9 @@ impl DeviceSelector {
7779 break ; // We are done here. The selected device continues without us.
7880 }
7981 DeviceSelectorEvent :: DevicesAdded ( ids) => {
82+ if ids. is_empty ( ) && waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
83+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
84+ }
8085 for id in ids {
8186 debug ! ( "Device added event: {:?}" , id) ;
8287 waiting_for_response. insert ( id) ;
@@ -99,9 +104,15 @@ impl DeviceSelector {
99104 tokens. retain ( |dev_id, _| dev_id != id) ;
100105 if tokens. is_empty ( ) {
101106 blinking = false ;
107+ if waiting_for_response. is_empty ( ) {
108+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
109+ }
102110 continue ;
103111 }
104112 }
113+ if waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
114+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
115+ }
105116 // We are already blinking, so no need to run the code below this match
106117 // that figures out if we should blink or not. In fact, currently, we do
107118 // NOT want to run this code again, because if you have 2 blinking tokens
@@ -115,6 +126,9 @@ impl DeviceSelector {
115126 DeviceSelectorEvent :: NotAToken ( ref id) => {
116127 debug ! ( "Device not a token event: {:?}" , id) ;
117128 waiting_for_response. remove ( id) ;
129+ if waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
130+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
131+ }
118132 }
119133 DeviceSelectorEvent :: ImAToken ( ( id, tx) ) => {
120134 let _ = waiting_for_response. remove ( & id) ;
@@ -187,6 +201,7 @@ pub mod tests {
187201 transport:: FidoDevice ,
188202 u2ftypes:: U2FDeviceInfo ,
189203 } ;
204+ use std:: sync:: mpsc:: TryRecvError ;
190205
191206 fn gen_info ( id : String ) -> U2FDeviceInfo {
192207 U2FDeviceInfo {
@@ -267,9 +282,10 @@ pub mod tests {
267282 Device :: new( "device selector 4" ) . unwrap( ) ,
268283 ] ;
269284
285+ let ( tx, rx) = channel ( ) ;
270286 // Make those actual tokens. The rest is interpreted as non-u2f-devices
271287 make_device_with_pin ( & mut devices[ 2 ] ) ;
272- let selector = DeviceSelector :: run ( ) ;
288+ let selector = DeviceSelector :: run ( tx ) ;
273289
274290 // Adding all
275291 add_devices ( devices. iter ( ) , & selector) ;
@@ -278,6 +294,7 @@ pub mod tests {
278294 send_no_token ( d, & selector) ;
279295 }
280296 } ) ;
297+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
281298
282299 send_i_am_token ( & devices[ 2 ] , & selector) ;
283300
@@ -292,18 +309,24 @@ pub mod tests {
292309 fn test_device_selector_stop ( ) {
293310 let device = Device :: new ( "device selector 1" ) . unwrap ( ) ;
294311
295- let mut selector = DeviceSelector :: run ( ) ;
312+ let ( tx, rx) = channel ( ) ;
313+ let mut selector = DeviceSelector :: run ( tx) ;
296314
297315 // Adding all
298316 selector
299317 . clone_sender ( )
300318 . send ( DeviceSelectorEvent :: DevicesAdded ( vec ! [ device. id( ) ] ) )
301319 . unwrap ( ) ;
320+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
302321
303322 selector
304323 . clone_sender ( )
305324 . send ( DeviceSelectorEvent :: NotAToken ( device. id ( ) ) )
306325 . unwrap ( ) ;
326+ assert_matches ! (
327+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
328+ Ok ( StatusUpdate :: NoDevicesFound )
329+ ) ;
307330 selector. stop ( ) ;
308331 }
309332
@@ -323,7 +346,8 @@ pub mod tests {
323346 make_device_with_pin ( & mut devices[ 4 ] ) ;
324347 make_device_with_pin ( & mut devices[ 5 ] ) ;
325348
326- let selector = DeviceSelector :: run ( ) ;
349+ let ( tx, rx) = channel ( ) ;
350+ let selector = DeviceSelector :: run ( tx) ;
327351
328352 // Adding all, except the last one (we simulate that this one is not yet plugged in)
329353 add_devices ( devices. iter ( ) . take ( 5 ) , & selector) ;
@@ -355,6 +379,7 @@ pub mod tests {
355379 devices[ 5 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
356380 DeviceCommand :: Blink
357381 ) ;
382+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
358383 }
359384
360385 #[ test]
@@ -375,7 +400,8 @@ pub mod tests {
375400 make_device_simple_u2f ( & mut devices[ 4 ] ) ;
376401 make_device_simple_u2f ( & mut devices[ 5 ] ) ;
377402
378- let selector = DeviceSelector :: run ( ) ;
403+ let ( tx, rx) = channel ( ) ;
404+ let selector = DeviceSelector :: run ( tx) ;
379405
380406 // Adding all, except the last one (we simulate that this one is not yet plugged in)
381407 add_devices ( devices. iter ( ) . take ( 5 ) , & selector) ;
@@ -417,6 +443,7 @@ pub mod tests {
417443 devices[ 6 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
418444 DeviceCommand :: Blink
419445 ) ;
446+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
420447 }
421448
422449 #[ test]
@@ -437,7 +464,8 @@ pub mod tests {
437464 make_device_with_pin ( & mut devices[ 4 ] ) ;
438465 make_device_with_pin ( & mut devices[ 5 ] ) ;
439466
440- let selector = DeviceSelector :: run ( ) ;
467+ let ( tx, rx) = channel ( ) ;
468+ let selector = DeviceSelector :: run ( tx) ;
441469
442470 // Adding all, except the last one (we simulate that this one is not yet plugged in)
443471 add_devices ( devices. iter ( ) , & selector) ;
@@ -456,11 +484,16 @@ pub mod tests {
456484 DeviceCommand :: Blink
457485 ) ;
458486 }
487+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
459488
460489 // Remove all tokens
461490 for idx in [ 2 , 4 , 5 ] {
462491 remove_device ( & devices[ idx] , & selector) ;
463492 }
493+ assert_matches ! (
494+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
495+ Ok ( StatusUpdate :: NoDevicesFound )
496+ ) ;
464497
465498 // Adding one again
466499 send_i_am_token ( & devices[ 4 ] , & selector) ;
@@ -471,4 +504,56 @@ pub mod tests {
471504 DeviceCommand :: Continue
472505 ) ;
473506 }
507+
508+ #[ test]
509+ fn test_device_selector_no_devices ( ) {
510+ let mut devices = vec ! [
511+ Device :: new( "device selector 1" ) . unwrap( ) ,
512+ Device :: new( "device selector 2" ) . unwrap( ) ,
513+ Device :: new( "device selector 3" ) . unwrap( ) ,
514+ Device :: new( "device selector 4" ) . unwrap( ) ,
515+ ] ;
516+
517+ let ( tx, rx) = channel ( ) ;
518+ // Make those actual tokens. The rest is interpreted as non-u2f-devices
519+ make_device_with_pin ( & mut devices[ 2 ] ) ;
520+ make_device_with_pin ( & mut devices[ 3 ] ) ;
521+ let selector = DeviceSelector :: run ( tx) ;
522+
523+ // Adding no devices first (none are plugged in when we start)
524+ add_devices ( std:: iter:: empty ( ) , & selector) ;
525+ assert_matches ! (
526+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
527+ Ok ( StatusUpdate :: NoDevicesFound )
528+ ) ;
529+
530+ // Adding the devices
531+ add_devices ( devices. iter ( ) , & selector) ;
532+ devices. iter_mut ( ) . for_each ( |d| {
533+ if !d. is_u2f ( ) {
534+ send_no_token ( d, & selector) ;
535+ }
536+ } ) ;
537+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
538+
539+ send_i_am_token ( & devices[ 2 ] , & selector) ;
540+ send_i_am_token ( & devices[ 3 ] , & selector) ;
541+
542+ assert_eq ! (
543+ devices[ 2 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
544+ DeviceCommand :: Blink
545+ ) ;
546+ assert_eq ! (
547+ devices[ 3 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
548+ DeviceCommand :: Blink
549+ ) ;
550+
551+ // Removing all blinking devices
552+ remove_device ( & devices[ 2 ] , & selector) ;
553+ remove_device ( & devices[ 3 ] , & selector) ;
554+ assert_matches ! (
555+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
556+ Ok ( StatusUpdate :: NoDevicesFound )
557+ ) ;
558+ }
474559}
0 commit comments