device: Treat devices as closed even after a close failure

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 commit is contained in:
Benjamin Berg 2020-11-16 19:16:53 +01:00
parent b6dd522459
commit 0051ff6352
2 changed files with 28 additions and 26 deletions

View file

@ -976,17 +976,17 @@ fpi_device_close_complete (FpDevice *device, GError *error)
return; return;
} }
if (!error) /* Always consider the device closed. Drivers should try hard to close the
{ * device. Generally, e.g. cancellations should be ignored.
*/
priv->is_open = FALSE; priv->is_open = FALSE;
g_object_notify (G_OBJECT (device), "open"); g_object_notify (G_OBJECT (device), "open");
if (!error)
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL, fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_BOOL,
GUINT_TO_POINTER (TRUE)); GUINT_TO_POINTER (TRUE));
}
else else
{
fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error); fpi_device_return_task_in_idle (device, FP_DEVICE_TASK_RETURN_ERROR, error);
}
} }
/** /**

View file

@ -588,7 +588,7 @@ test_driver_close_error (void)
g_assert (fake_dev->last_called_function == dev_class->close); g_assert (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL); g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error)); g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_true (fp_device_is_open (device)); g_assert_false (fp_device_is_open (device));
} }
static void static void
@ -2069,12 +2069,6 @@ test_driver_action_error_all (void)
fake_dev->return_action_error = TRUE; fake_dev->return_action_error = TRUE;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_close_sync (device, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID); fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_null (fp_device_enroll_sync (device, fp_print_new (device), NULL, g_assert_null (fp_device_enroll_sync (device, fp_print_new (device), NULL,
NULL, NULL, &error)); NULL, NULL, &error));
@ -2113,6 +2107,13 @@ test_driver_action_error_all (void)
g_assert_true (fake_dev->last_called_function == dev_class->delete); g_assert_true (fake_dev->last_called_function == dev_class->delete);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID); g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error); g_clear_error (&error);
/* Test close last, as we can't operate on a closed device. */
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_close_sync (device, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
} }
static void static void
@ -2146,16 +2147,6 @@ test_driver_action_error_fallback_all (void)
"error function*"); "error function*");
fake_dev->return_action_error = TRUE; fake_dev->return_action_error = TRUE;
g_assert_false (fp_device_close_sync (device, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_null (fp_device_enroll_sync (device, fp_print_new (device), NULL, g_assert_null (fp_device_enroll_sync (device, fp_print_new (device), NULL,
NULL, NULL, &error)); NULL, NULL, &error));
g_test_assert_expected_messages (); g_test_assert_expected_messages ();
@ -2215,6 +2206,17 @@ test_driver_action_error_fallback_all (void)
g_assert_true (fake_dev->last_called_function == dev_class->delete); g_assert_true (fake_dev->last_called_function == dev_class->delete);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL); g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error); g_clear_error (&error);
/* Test close last, as we can't operate on a closed device. */
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_false (fp_device_close_sync (device, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
} }
static void static void