Reviewed on: 2024-05-30
activity
is a library for creating an activity service.
The activity service, implemented as ActivityManager
, is a service which reports whether user input activity has happened recently as reported to the input pipeline.
The service is Active
on startup and will remain Active
as it receives activity reports. The service will transition to Idle
after a certain amount of time, known as the idle transition threshold, has transpired since the last activity was reported to the service, e.g. 100 milliseconds.
Products may configure this threshold using structured configuration.
If the service receives activity reports after transitioning to Idle
, it will transition back to the Active
state.
On startup or with activity ┌──────────┐ │ ┌──────┐ │ ┌────┐ └>│Active│─┘ │Idle│ └──┬───┘ └─┬──┘ │ │ │No activity for X amount of time│ │───────────────────────────────>│ │ │ │ Activity │ │<───────────────────────────────│ ┌──┴───┐ ┌─┴──┐ │Active│ │Idle│ └──────┘ └────┘
Where X = idle transition threshold
InputHandlers
registered in the input pipeline can report to the activity service via fuchsia.input.interaction.observation.Aggregator/ReportDiscreteActivity
, which will take the time of the activity and serve an acknowledgement of reception.
use fidl_fuchsia_input_interaction_observation as interaction_observation; use fuchsia_component::client::connect_to_protocol; let aggregator_proxy = connect_to_protocol::<interaction_observation::AggregatorMarker>()?; aggregator_proxy.report_discrete_activity( event_time.into_nanos()).await.expect("Failed to report activity");
Clients can subscribe to the activity service's transitions in activity state via fuchsia.input.interaction.Notifier/WatchState
, which follows a hanging-get pattern.
The server will always respond immediately with the initial state, and after that whenever the system's state changes.
use async_utils::hanging_get::client::HangingGetStream; use fidl_fuchsia_input_interaction::{NotifierMarker, NotifierProxy}; use fuchsia_component::client::connect_to_protocol; let notifier_proxy = connect_to_protocol::<NotifierMarker>()?; let mut watch_activity_state_stream = HangingGetStream::new(notifier_proxy, NotifierProxy::watch_state); while let Some(Ok(state)) = watch_activity_state_stream.next().await { match state { State::Active => {/* do something */}, State::Idle => {/* do something */} } }
Some clients may be interested in implementing functionality far deeper into idleness than the service currently supports. As more concrete use cases arise, the service could be extended to meet growing needs. In the mean time, there are still ways the service can be used to meet certain goals.
For example, if the activity service transitioned to idle 100 milliseconds after the last user input activity, but a client wanted to do something only after it knew that a user has been idle for 1 second, it is still possible to use the current API to accomplish these goals.
It is recommended in this case to still subscribe to activity state changes via fuchsia.input.interaction.Notifier/WatchState
and implement your own timers beyond. One such approach might look like:
Idle
state.Active
state before the timer elapses, cancel the timer.