This tests all relevant scenarios of device removal, i.e.:
* device is not open
* device is currently closing
* device is open and idle
* device is currently opening
* device is open and active
The test ensures that in all scenarios the following holds true:
* device "removed" signal is only emitted after the action completes
* context "device-removed" signal is only emitted after the device has
been closed
Note that the "opening" case is special. Here we confirm that a success
from "open" will not be overriden by a FP_DEVICE_ERROR_REMOVED error, in
order to correctly signal that the internal device state is open and it
needs to be closed.
In general, we rely on the underlying transport layer to throw errors
which will abort the current operation. This does not work for the
virtual image device though, but we need it there for testing purposes.
Add a notify::removed handler that makes things work as expected. Let it
throw a protocol error which should not be visible to the outside.
We require the close call, but as the underlying transport layer is
gone, it will generally just return an error.
In principle, it makes sense to think of close as a function that always
succeeds (i.e. it makes no sense to try again). Should the device be in
a bad state, then a subsequent open() will simply fail.
This enhances the device removal to create a well defined behaviour.
Primarily, it means that:
* "device-removed" will only be called for closed devices
* "removed" will be called only when no operation is active
Note that all actions will fail with FP_DEVICE_ERROR_REMOVED, *except*
for open which will only return this error if it failed.
Resolves: #330
When a new connection came in we would close the old connection. This in
turn would trigger a receive error causing the *new* connection to be
closed from the error handler.
Fix this by simply cancelling any pending transfers when a new
connection comes in. Also change the error handling code to catch issues
like partial writes correctly.
This fixes an issue for the fprintd test where some tests were flaky.
Some devices have storage but that's is limited enough not to be able
to store all the metadata, but just a fingerprint id.
In such case we also need to use the local storage to be able to verify.
Fprintd does this already, but we don't do it in the libfprint examples.
So, in in case we enroll, always save the print information to the disk,
while in case we verify we try to load the print from disk and we use
that in case its private data matches the one provided by the device.
While the image device has its own finger status tracking, we use a simpler
version as public data information, so let's just report the finger-on/off
and when a finger is expected to the parent class.
Verify that this happens as expected using the virtual-image class
It is not very useful to just delete the data again after a failure, as
it might be useful for debugging. Just store it into an "errors"
subdirectory of the PWD in the hope that this is a sane location.
Note that it'll error out if the directory already exists, but that
should be acceptable in all cases. i.e. it won't exist in the CI and
developers can just wipe the directory.
When porting the driver to the new libfprint 1.90.0 a mistake was made
where the device was not passed through user_data anymore but it was
still read from there. Stop using user_data in the callback to fix this.
See: #320
The elan driver always "deactivates" the device after a cpature run. We
can simplify the while internal state into a single "active" state and
rely on the image device driving this state machine correctly.
i.e.:
* We start a callibrate/capture/deactivate when we go into the
AWAIT_FINGER_ON state
* We only store the fact that we are active and want to deactivate
* We rely on the image device never going into the AWAIT_FINGER_ON
state without first waiting for the finger to be off (which implies
deactivation).
This adds a number of new internal states to better capture what is
going on. Also added are checks that all transitions we make are in the
set of expected and valid transitions.
Only three drivers use the state_change notification. These drivers are
updated accordingly.
The boolean is just used to emit a warning for unexpected state
transitions. It is sufficient to pass it to the deactivate function
directly for that purpose.
We might redo image transfers, but we only ever had one reference that
was implicitly removed after the transfer completed. Add a new reference
each time it is submitted and only free the last reference in the stop
handler.
For some reason we re-submitted the interrupt transfer with a timeout of
1s while the original submission was without a timeout. This looks like
typo, remove the timeout.
Annotate the USB transfer creation functions with the correct buffer
access attribute. Note that we only annotate them as read_only as the
functions may be used for sending and receiving.
Hopefully this will catch buffer overflows in drivers in the future.
Doing this avoids race conditions in testing code where the code might
try to submit errors/images before the device has been activated. This
would then (sometimes) trigger assertions in the image driver code.
The earlier image device code tried to hide deactivation from the
surrounding library. However, this does not make any sense anymore with
the early reporting feature present.
This changes the operation to complete only once the device is
deactivated. Also changed that in most cases (except for cancellation)
we wait for the finger to be removed before deactivating the device.
The driver seems to have relied on the device to be fully
deactivated and activated again for each capture. This is not the case
during enroll, and as such in can cause issues.
Try fixing this by splitting out the last few commands send to the
device and assuming that this starts the capture.
Fixes: #306
We have plenty of code paths where a transfer may be cancelled before it
is submitted. Unfortunately, libgusb up to and including version 0.3.6
are not handling that case correctly (due to libusb ignoring
cancellation on transfers that are not yet submitted).
Work around this, but do so in a somewhat lazy fashion that is not
entirely race free.
Closes: #306
Delay the open/close callbacks by 100ms so that we have a window of
opportunity for race conditions. This is needed to test certain
conditiosn in fprintd.
Adding a trailing \n to g_message, g_debug, g_warning and g_error is not
neccessary, as a newline will be added automatically by the logging
infrastructure.
The cancellable needs to be free'ed at deactivation. Also free it if we
run into a fatal error, which then in turn indicates that the device is
deactivated already.
The change_state function is called synchronously from the
image_captured callback. This means that deactivation of the device
happens during the img_cb function, causing the USB transfer to be
re-registered even though the device is already deactivating.
There are various ways to fix this, but it makes sense to directly bind
the cancellation to the deactivation. So create a cancellable that we
cancel at deactivation time, and make sure we always deactivate by going
through cancellation.
closes: #306