virtual-device: Process supported commands on device open

When opening the device we can process commands that we left for that
after the previous close, to do that we only have to inject an invalid
command that will be processed (and ignored) while closing, so that at
next device opening we will be able to proceed with the previously
sent commands.

Add tests to finally check this case!
This commit is contained in:
Marco Trevisan (Treviño) 2021-01-28 01:16:12 +01:00
parent e1e3f6955e
commit 51009b48a0
2 changed files with 60 additions and 1 deletions

View file

@ -78,6 +78,10 @@ maybe_continue_current_action (FpDeviceVirtualDevice *self)
FP_DEVICE_GET_CLASS (self)->delete (dev); FP_DEVICE_GET_CLASS (self)->delete (dev);
break; break;
case FPI_DEVICE_ACTION_OPEN:
FP_DEVICE_GET_CLASS (self)->open (dev);
break;
case FPI_DEVICE_ACTION_CLOSE: case FPI_DEVICE_ACTION_CLOSE:
FP_DEVICE_GET_CLASS (self)->close (dev); FP_DEVICE_GET_CLASS (self)->close (dev);
break; break;
@ -327,6 +331,22 @@ dev_init (FpDevice *dev)
G_DEBUG_HERE (); G_DEBUG_HERE ();
process_cmds (self, FALSE, &error);
if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
fpi_device_open_complete (dev, g_steal_pointer (&error));
return;
}
else if (self->sleep_timeout_id)
{
return;
}
else if (self->listener)
{
fpi_device_open_complete (dev, NULL);
return;
}
listener = fp_device_virtual_listener_new (); listener = fp_device_virtual_listener_new ();
cancellable = g_cancellable_new (); cancellable = g_cancellable_new ();

View file

@ -123,7 +123,7 @@ class VirtualDevice(unittest.TestCase):
def send_command(self, command, *args): def send_command(self, command, *args):
self.assertIn(command, ['INSERT', 'REMOVE', 'SCAN', 'ERROR', 'RETRY', self.assertIn(command, ['INSERT', 'REMOVE', 'SCAN', 'ERROR', 'RETRY',
'FINGER', 'UNPLUG', 'SLEEP', 'SET_ENROLL_STAGES', 'SET_SCAN_TYPE', 'FINGER', 'UNPLUG', 'SLEEP', 'SET_ENROLL_STAGES', 'SET_SCAN_TYPE',
'SET_CANCELLATION_ENABLED']) 'SET_CANCELLATION_ENABLED', 'IGNORED_COMMAND'])
with Connection(self.sockaddr) as con: with Connection(self.sockaddr) as con:
params = ' '.join(str(p) for p in args) params = ' '.join(str(p) for p in args)
@ -333,6 +333,45 @@ class VirtualDevice(unittest.TestCase):
self.assertFalse(self.dev.supports_capture()) self.assertFalse(self.dev.supports_capture())
self.assertFalse(self.dev.has_storage()) self.assertFalse(self.dev.has_storage())
def test_open_error(self):
self._close_on_teardown = False
self.send_command('IGNORED_COMMAND') # This will be consumed by close
self.send_error(FPrint.DeviceError.PROTO) # This will be consumed by open
with GLibErrorMessage('libfprint-virtual_device',
GLib.LogLevelFlags.LEVEL_WARNING, 'Could not process command: *'):
self.dev.close_sync()
with self.assertRaises(GLib.Error) as error:
self.dev.open_sync()
self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(),
FPrint.DeviceError.PROTO))
def test_delayed_open(self):
self.send_command('IGNORED_COMMAND') # This will be consumed by close
self.send_sleep(500) # This will be consumed by open
with GLibErrorMessage('libfprint-virtual_device',
GLib.LogLevelFlags.LEVEL_WARNING, 'Could not process command: *'):
self.dev.close_sync()
opened = False
def on_opened(dev, res):
nonlocal opened
dev.open_finish(res)
opened = True
self.dev.open(callback=on_opened)
self.wait_timeout(10)
self.assertFalse(self.dev.is_open())
self.wait_timeout(10)
self.assertFalse(self.dev.is_open())
while not opened:
ctx.iteration(True)
def test_enroll(self): def test_enroll(self):
matching = self.enroll_print('testprint', FPrint.Finger.LEFT_LITTLE) matching = self.enroll_print('testprint', FPrint.Finger.LEFT_LITTLE)
self.assertEqual(matching.get_username(), 'testuser') self.assertEqual(matching.get_username(), 'testuser')