fpi-ssm: Make delayed actions cancellable
Add a GCancellable parameter to fpi_ssm_nex_state_delayed and fpi_ssm_jump_to_state_delayed() so that it's possible to cancel an action from the caller and in case the driver wants to cancel a delayed operation when a device action has been cancelled.
This commit is contained in:
parent
bac6382f67
commit
ff67bf5a16
8 changed files with 127 additions and 41 deletions
|
@ -752,7 +752,7 @@ calibrate_run_state (FpiSsm *ssm, FpDevice *dev)
|
||||||
if (self->calib_status == 0x00 &&
|
if (self->calib_status == 0x00 &&
|
||||||
self->last_read[0] == 0x01)
|
self->last_read[0] == 0x01)
|
||||||
self->calib_status = 0x01;
|
self->calib_status = 0x01;
|
||||||
fpi_ssm_next_state_delayed (ssm, 50);
|
fpi_ssm_next_state_delayed (ssm, 50, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -864,7 +864,7 @@ rebootpwr_run_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_ssm_jump_to_state_delayed (ssm, 10, REBOOTPWR_GET_HWSTAT);
|
fpi_ssm_jump_to_state_delayed (ssm, 10, REBOOTPWR_GET_HWSTAT, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -946,11 +946,11 @@ powerup_run_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
}
|
}
|
||||||
else if (!self->profile->auth_cr)
|
else if (!self->profile->auth_cr)
|
||||||
{
|
{
|
||||||
fpi_ssm_jump_to_state_delayed (ssm, POWERUP_SET_HWSTAT, 10);
|
fpi_ssm_jump_to_state_delayed (ssm, POWERUP_SET_HWSTAT, 10, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpi_ssm_next_state_delayed (ssm, 10);
|
fpi_ssm_next_state_delayed (ssm, 10, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -608,7 +608,7 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
|
||||||
clear_data (self);
|
clear_data (self);
|
||||||
|
|
||||||
/* Wait for probable vdev->active changing */
|
/* Wait for probable vdev->active changing */
|
||||||
fpi_ssm_next_state_delayed (ssm, VFS_SSM_TIMEOUT);
|
fpi_ssm_next_state_delayed (ssm, VFS_SSM_TIMEOUT, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSM_NEXT_RECEIVE:
|
case SSM_NEXT_RECEIVE:
|
||||||
|
@ -627,7 +627,8 @@ activate_ssm (FpiSsm *ssm, FpDevice *dev)
|
||||||
|
|
||||||
case SSM_WAIT_ANOTHER_SCAN:
|
case SSM_WAIT_ANOTHER_SCAN:
|
||||||
/* Orange light is on now */
|
/* Orange light is on now */
|
||||||
fpi_ssm_jump_to_state_delayed (ssm, SSM_TURN_ON, VFS_SSM_ORANGE_TIMEOUT);
|
fpi_ssm_jump_to_state_delayed (ssm, SSM_TURN_ON, VFS_SSM_ORANGE_TIMEOUT,
|
||||||
|
NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -785,7 +785,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
|
|
||||||
case M_LOOP_0_SLEEP:
|
case M_LOOP_0_SLEEP:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
fpi_ssm_next_state_delayed (ssm, 50);
|
fpi_ssm_next_state_delayed (ssm, 50, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_0_GET_STATE:
|
case M_LOOP_0_GET_STATE:
|
||||||
|
@ -828,7 +828,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
img_extract (ssm, dev);
|
img_extract (ssm, dev);
|
||||||
|
|
||||||
/* Wait handling image */
|
/* Wait handling image */
|
||||||
fpi_ssm_next_state_delayed (ssm, 10);
|
fpi_ssm_next_state_delayed (ssm, 10, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_0_CHECK_ACTION:
|
case M_LOOP_0_CHECK_ACTION:
|
||||||
|
@ -851,7 +851,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
if (vfs_finger_state (self) == VFS_FINGER_PRESENT)
|
if (vfs_finger_state (self) == VFS_FINGER_PRESENT)
|
||||||
{
|
{
|
||||||
fpi_image_device_report_finger_status (dev, TRUE);
|
fpi_image_device_report_finger_status (dev, TRUE);
|
||||||
fpi_ssm_next_state_delayed (ssm, 250);
|
fpi_ssm_next_state_delayed (ssm, 250, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -881,7 +881,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
|
|
||||||
case M_LOOP_1_SLEEP:
|
case M_LOOP_1_SLEEP:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
fpi_ssm_next_state_delayed (ssm, 10);
|
fpi_ssm_next_state_delayed (ssm, 10, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_LOOP_2_ABORT_PRINT:
|
case M_LOOP_2_ABORT_PRINT:
|
||||||
|
@ -917,7 +917,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
{
|
{
|
||||||
/* Wait aborting */
|
/* Wait aborting */
|
||||||
self->counter++;
|
self->counter++;
|
||||||
fpi_ssm_next_state_delayed (ssm, 100);
|
fpi_ssm_next_state_delayed (ssm, 100, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1055,7 +1055,7 @@ m_init_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
{
|
{
|
||||||
/* Wait aborting */
|
/* Wait aborting */
|
||||||
self->counter++;
|
self->counter++;
|
||||||
fpi_ssm_next_state_delayed (ssm, 100);
|
fpi_ssm_next_state_delayed (ssm, 100, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1084,7 +1084,7 @@ m_init_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
{
|
{
|
||||||
/* Wait removing finger */
|
/* Wait removing finger */
|
||||||
self->counter++;
|
self->counter++;
|
||||||
fpi_ssm_next_state_delayed (ssm, 250);
|
fpi_ssm_next_state_delayed (ssm, 250, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,7 +97,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
|
|
||||||
case M_WAIT_PRINT:
|
case M_WAIT_PRINT:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
fpi_ssm_next_state_delayed (ssm, 200);
|
fpi_ssm_next_state_delayed (ssm, 200, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_CHECK_PRINT:
|
case M_CHECK_PRINT:
|
||||||
|
@ -115,7 +115,7 @@ m_loop_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
|
|
||||||
case M_READ_PRINT_WAIT:
|
case M_READ_PRINT_WAIT:
|
||||||
/* Wait fingerprint scanning */
|
/* Wait fingerprint scanning */
|
||||||
fpi_ssm_next_state_delayed (ssm, 200);
|
fpi_ssm_next_state_delayed (ssm, 200, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case M_READ_PRINT_POLL:
|
case M_READ_PRINT_POLL:
|
||||||
|
|
|
@ -704,7 +704,7 @@ activate_loop (FpiSsm *ssm, FpDevice *_dev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEV_ACTIVATE_DATA_COMPLETE:
|
case DEV_ACTIVATE_DATA_COMPLETE:
|
||||||
fpi_ssm_next_state_delayed (ssm, 1);
|
fpi_ssm_next_state_delayed (ssm, 1, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEV_ACTIVATE_PREPARE_NEXT_CAPTURE:
|
case DEV_ACTIVATE_PREPARE_NEXT_CAPTURE:
|
||||||
|
|
|
@ -88,6 +88,8 @@ struct _FpiSsm
|
||||||
int cur_state;
|
int cur_state;
|
||||||
gboolean completed;
|
gboolean completed;
|
||||||
GSource *timeout;
|
GSource *timeout;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
gulong cancellable_id;
|
||||||
GError *error;
|
GError *error;
|
||||||
FpiSsmCompletedCallback callback;
|
FpiSsmCompletedCallback callback;
|
||||||
FpiSsmHandlerCallback handler;
|
FpiSsmHandlerCallback handler;
|
||||||
|
@ -155,6 +157,81 @@ fpi_ssm_get_data (FpiSsm *machine)
|
||||||
return machine->ssm_data;
|
return machine->ssm_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_ssm_clear_delayed_action (FpiSsm *machine)
|
||||||
|
{
|
||||||
|
if (machine->cancellable_id)
|
||||||
|
{
|
||||||
|
g_cancellable_disconnect (machine->cancellable, machine->cancellable_id);
|
||||||
|
machine->cancellable_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&machine->cancellable);
|
||||||
|
g_clear_pointer (&machine->timeout, g_source_destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _CancelledActionIdleData
|
||||||
|
{
|
||||||
|
gulong cancellable_id;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
} CancelledActionIdleData;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
on_delayed_action_cancelled_idle (gpointer user_data)
|
||||||
|
{
|
||||||
|
CancelledActionIdleData *data = user_data;
|
||||||
|
|
||||||
|
g_cancellable_disconnect (data->cancellable, data->cancellable_id);
|
||||||
|
g_object_unref (data->cancellable);
|
||||||
|
g_free (data);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_delayed_action_cancelled (GCancellable *cancellable,
|
||||||
|
FpiSsm *machine)
|
||||||
|
{
|
||||||
|
CancelledActionIdleData *data;
|
||||||
|
|
||||||
|
g_clear_pointer (&machine->timeout, g_source_destroy);
|
||||||
|
|
||||||
|
data = g_new0 (CancelledActionIdleData, 1);
|
||||||
|
data->cancellable = g_steal_pointer (&machine->cancellable);
|
||||||
|
data->cancellable_id = machine->cancellable_id;
|
||||||
|
machine->cancellable_id = 0;
|
||||||
|
|
||||||
|
g_idle_add_full (G_PRIORITY_HIGH_IDLE, on_delayed_action_cancelled_idle,
|
||||||
|
data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fpi_ssm_set_delayed_action_timeout (FpiSsm *machine,
|
||||||
|
int delay,
|
||||||
|
FpTimeoutFunc callback,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify destroy_func)
|
||||||
|
{
|
||||||
|
BUG_ON (machine->completed);
|
||||||
|
BUG_ON (machine->timeout != NULL);
|
||||||
|
|
||||||
|
fpi_ssm_clear_delayed_action (machine);
|
||||||
|
|
||||||
|
if (cancellable != NULL)
|
||||||
|
{
|
||||||
|
g_set_object (&machine->cancellable, cancellable);
|
||||||
|
|
||||||
|
machine->cancellable_id =
|
||||||
|
g_cancellable_connect (machine->cancellable,
|
||||||
|
G_CALLBACK (on_delayed_action_cancelled),
|
||||||
|
machine, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
machine->timeout = fpi_device_add_timeout (machine->dev, delay, callback,
|
||||||
|
user_data, destroy_func);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fpi_ssm_free:
|
* fpi_ssm_free:
|
||||||
* @machine: an #FpiSsm state machine
|
* @machine: an #FpiSsm state machine
|
||||||
|
@ -173,7 +250,7 @@ fpi_ssm_free (FpiSsm *machine)
|
||||||
if (machine->ssm_data_destroy)
|
if (machine->ssm_data_destroy)
|
||||||
g_clear_pointer (&machine->ssm_data, machine->ssm_data_destroy);
|
g_clear_pointer (&machine->ssm_data, machine->ssm_data_destroy);
|
||||||
g_clear_pointer (&machine->error, g_error_free);
|
g_clear_pointer (&machine->error, g_error_free);
|
||||||
g_clear_pointer (&machine->timeout, g_source_destroy);
|
fpi_ssm_clear_delayed_action (machine);
|
||||||
g_free (machine);
|
g_free (machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +331,8 @@ fpi_ssm_mark_completed (FpiSsm *machine)
|
||||||
BUG_ON (machine->completed);
|
BUG_ON (machine->completed);
|
||||||
BUG_ON (machine->timeout != NULL);
|
BUG_ON (machine->timeout != NULL);
|
||||||
|
|
||||||
g_clear_pointer (&machine->timeout, g_source_destroy);
|
fpi_ssm_clear_delayed_action (machine);
|
||||||
|
|
||||||
machine->completed = TRUE;
|
machine->completed = TRUE;
|
||||||
|
|
||||||
if (machine->error)
|
if (machine->error)
|
||||||
|
@ -309,7 +387,7 @@ fpi_ssm_next_state (FpiSsm *machine)
|
||||||
BUG_ON (machine->completed);
|
BUG_ON (machine->completed);
|
||||||
BUG_ON (machine->timeout != NULL);
|
BUG_ON (machine->timeout != NULL);
|
||||||
|
|
||||||
g_clear_pointer (&machine->timeout, g_source_destroy);
|
fpi_ssm_clear_delayed_action (machine);
|
||||||
|
|
||||||
machine->cur_state++;
|
machine->cur_state++;
|
||||||
if (machine->cur_state == machine->nr_states)
|
if (machine->cur_state == machine->nr_states)
|
||||||
|
@ -325,7 +403,7 @@ fpi_ssm_cancel_delayed_state_change (FpiSsm *machine)
|
||||||
BUG_ON (machine->completed);
|
BUG_ON (machine->completed);
|
||||||
BUG_ON (machine->timeout == NULL);
|
BUG_ON (machine->timeout == NULL);
|
||||||
|
|
||||||
g_clear_pointer (&machine->timeout, g_source_destroy);
|
fpi_ssm_clear_delayed_action (machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -342,24 +420,25 @@ on_device_timeout_next_state (FpDevice *dev,
|
||||||
* fpi_ssm_next_state_delayed:
|
* fpi_ssm_next_state_delayed:
|
||||||
* @machine: an #FpiSsm state machine
|
* @machine: an #FpiSsm state machine
|
||||||
* @delay: the milliseconds to wait before switching to the next state
|
* @delay: the milliseconds to wait before switching to the next state
|
||||||
|
* @cancellable: (nullable): a #GCancellable to cancel the delayed operation
|
||||||
*
|
*
|
||||||
* Iterate to next state of a state machine with a delay of @delay ms. If the
|
* Iterate to next state of a state machine with a delay of @delay ms. If the
|
||||||
* current state is the last state, then the state machine will be marked as
|
* current state is the last state, then the state machine will be marked as
|
||||||
* completed, as if calling fpi_ssm_mark_completed().
|
* completed, as if calling fpi_ssm_mark_completed().
|
||||||
|
* Passing a valid #GCancellable will cause the action to be cancelled when
|
||||||
|
* @cancellable is.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_ssm_next_state_delayed (FpiSsm *machine,
|
fpi_ssm_next_state_delayed (FpiSsm *machine,
|
||||||
int delay)
|
int delay,
|
||||||
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
g_autofree char *source_name = NULL;
|
g_autofree char *source_name = NULL;
|
||||||
|
|
||||||
g_return_if_fail (machine != NULL);
|
g_return_if_fail (machine != NULL);
|
||||||
BUG_ON (machine->completed);
|
|
||||||
BUG_ON (machine->timeout != NULL);
|
|
||||||
|
|
||||||
g_clear_pointer (&machine->timeout, g_source_destroy);
|
fpi_ssm_set_delayed_action_timeout (machine, delay,
|
||||||
machine->timeout = fpi_device_add_timeout (machine->dev, delay,
|
on_device_timeout_next_state, cancellable,
|
||||||
on_device_timeout_next_state,
|
|
||||||
machine, NULL);
|
machine, NULL);
|
||||||
|
|
||||||
source_name = g_strdup_printf ("[%s] ssm %p jump to next state %d",
|
source_name = g_strdup_printf ("[%s] ssm %p jump to next state %d",
|
||||||
|
@ -384,7 +463,8 @@ fpi_ssm_jump_to_state (FpiSsm *machine, int state)
|
||||||
BUG_ON (state < 0 || state >= machine->nr_states);
|
BUG_ON (state < 0 || state >= machine->nr_states);
|
||||||
BUG_ON (machine->timeout != NULL);
|
BUG_ON (machine->timeout != NULL);
|
||||||
|
|
||||||
g_clear_pointer (&machine->timeout, g_source_destroy);
|
fpi_ssm_clear_delayed_action (machine);
|
||||||
|
|
||||||
machine->cur_state = state;
|
machine->cur_state = state;
|
||||||
__ssm_call_handler (machine);
|
__ssm_call_handler (machine);
|
||||||
}
|
}
|
||||||
|
@ -410,14 +490,18 @@ on_device_timeout_jump_to_state (FpDevice *dev,
|
||||||
* @machine: an #FpiSsm state machine
|
* @machine: an #FpiSsm state machine
|
||||||
* @state: the state to jump to
|
* @state: the state to jump to
|
||||||
* @delay: the milliseconds to wait before switching to @state state
|
* @delay: the milliseconds to wait before switching to @state state
|
||||||
|
* @cancellable: (nullable): a #GCancellable to cancel the delayed operation
|
||||||
*
|
*
|
||||||
* Jump to the @state state with a delay of @delay milliseconds, bypassing
|
* Jump to the @state state with a delay of @delay milliseconds, bypassing
|
||||||
* intermediary states.
|
* intermediary states.
|
||||||
|
* Passing a valid #GCancellable will cause the action to be cancelled when
|
||||||
|
* @cancellable is.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
||||||
int state,
|
int state,
|
||||||
int delay)
|
int delay,
|
||||||
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
FpiSsmJumpToStateDelayedData *data;
|
FpiSsmJumpToStateDelayedData *data;
|
||||||
g_autofree char *source_name = NULL;
|
g_autofree char *source_name = NULL;
|
||||||
|
@ -430,10 +514,9 @@ fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
||||||
data->machine = machine;
|
data->machine = machine;
|
||||||
data->next_state = state;
|
data->next_state = state;
|
||||||
|
|
||||||
g_clear_pointer (&machine->timeout, g_source_destroy);
|
fpi_ssm_set_delayed_action_timeout (machine, delay,
|
||||||
machine->timeout = fpi_device_add_timeout (machine->dev, delay,
|
|
||||||
on_device_timeout_jump_to_state,
|
on_device_timeout_jump_to_state,
|
||||||
data, g_free);
|
cancellable, data, g_free);
|
||||||
|
|
||||||
source_name = g_strdup_printf ("[%s] ssm %p jump to state %d",
|
source_name = g_strdup_printf ("[%s] ssm %p jump to state %d",
|
||||||
fp_device_get_device_id (machine->dev),
|
fp_device_get_device_id (machine->dev),
|
||||||
|
|
|
@ -74,10 +74,12 @@ void fpi_ssm_next_state (FpiSsm *machine);
|
||||||
void fpi_ssm_jump_to_state (FpiSsm *machine,
|
void fpi_ssm_jump_to_state (FpiSsm *machine,
|
||||||
int state);
|
int state);
|
||||||
void fpi_ssm_next_state_delayed (FpiSsm *machine,
|
void fpi_ssm_next_state_delayed (FpiSsm *machine,
|
||||||
int delay);
|
int delay,
|
||||||
|
GCancellable *cancellable);
|
||||||
void fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
void fpi_ssm_jump_to_state_delayed (FpiSsm *machine,
|
||||||
int state,
|
int state,
|
||||||
int delay);
|
int delay,
|
||||||
|
GCancellable *cancellable);
|
||||||
void fpi_ssm_cancel_delayed_state_change (FpiSsm *machine);
|
void fpi_ssm_cancel_delayed_state_change (FpiSsm *machine);
|
||||||
void fpi_ssm_mark_completed (FpiSsm *machine);
|
void fpi_ssm_mark_completed (FpiSsm *machine);
|
||||||
void fpi_ssm_mark_failed (FpiSsm *machine,
|
void fpi_ssm_mark_failed (FpiSsm *machine,
|
||||||
|
|
Loading…
Reference in a new issue