diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c index 6f83a057..1acfcfef 100644 --- a/libfprint/drivers/virtual-device.c +++ b/libfprint/drivers/virtual-device.c @@ -78,6 +78,10 @@ maybe_continue_current_action (FpDeviceVirtualDevice *self) FP_DEVICE_GET_CLASS (self)->delete (dev); break; + case FPI_DEVICE_ACTION_OPEN: + FP_DEVICE_GET_CLASS (self)->open (dev); + break; + case FPI_DEVICE_ACTION_CLOSE: FP_DEVICE_GET_CLASS (self)->close (dev); break; @@ -327,6 +331,22 @@ dev_init (FpDevice *dev) 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 (); cancellable = g_cancellable_new (); diff --git a/tests/virtual-device.py b/tests/virtual-device.py index 941b30cd..1b98abef 100644 --- a/tests/virtual-device.py +++ b/tests/virtual-device.py @@ -123,7 +123,7 @@ class VirtualDevice(unittest.TestCase): def send_command(self, command, *args): self.assertIn(command, ['INSERT', 'REMOVE', 'SCAN', 'ERROR', 'RETRY', 'FINGER', 'UNPLUG', 'SLEEP', 'SET_ENROLL_STAGES', 'SET_SCAN_TYPE', - 'SET_CANCELLATION_ENABLED']) + 'SET_CANCELLATION_ENABLED', 'IGNORED_COMMAND']) with Connection(self.sockaddr) as con: 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.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): matching = self.enroll_print('testprint', FPrint.Finger.LEFT_LITTLE) self.assertEqual(matching.get_username(), 'testuser')