Session State Management
Several of the HAL services follow the same session state management paradigm and share a common pattern for state transitions and notifications.
Any HAL service that handles AV data buffers will follow the session state management described in this section.
Where resource instances managed by a HAL service, often a sub-interface is offered to manage that specific resource (e.g. IAudioDecoderManager
provides IAudioDecoder
resource instance sub-interfaces). In this case each of the resource instances operates its own session state machine.
Not all states may be applicable to all HAL services, so check the relevant HAL service documentation.
HAL AIDL Definitions
See State.aidl
in Common.
Implementation Requirements
Requirement | Comments |
---|---|
HAL.STATE.1 | When a function is called which changes state, an initial onStateChanged() callback shall occur indicating the new transitory state within 10ms. |
HAL.STATE.2 | When a function is called which changes state, the final onStateChanged() callback shall occur indicating the new target state within 500ms. |
HAL Service Component States
When a service instance has finished initialising, its initial state is CLOSED
.
A HAL service notifies the client of state changes through the <Listener>.onStateChanged()
callback which is usually registered with the registerEventListener()
function.
The functions which cause a state transition; open()
, close()
, start()
, stop()
and flush()
cause the component to enter a transitory state for a period of time until it enters it target state. Both the transitory state change and target state change are both notified to the client through the onStateChanged()
callback.
If an internal error occurs during the OPENING
or STARTING
transitory states, then it cannot transition to the new target state, but instead returns to the previous state which is notified to the client through the onStateChanged()
callback.
enum State | State Type | Description |
---|---|---|
UNKNOWN | Transitory | The initial HAL service session state while initialising, before transitioning to the CLOSED state. |
CLOSED | Non-transitory | Initial state entered after initialisation. |
OPENING | Transitory | The HAL service session is transitioning from CLOSED to the READY state. |
READY | Non-transitory | The HAL service session is open and ready to start, but in a stopped state. |
STARTING | Transitory | The HAL service session is transitioning from READY to the STARTED state. |
STARTED | Non-transitory | The opened HAL service session has been started. |
FLUSHING | Transitory | The started HAL service session is flushing internal state/buffers. Once flushed, the HAL service session returns to the STARTED state. |
STOPPING | Transitory | The started HAL service session is stopping and flushing its internal state/buffers. Once flushed, the HAL service session enters the READY state. |
CLOSING | Transitory | The HAL service session is transitioning from READY to the CLOSED state. |
State Diagram
The state diagram below includes the typical function names which trigger state transitions.
Transitory states are only held while the HAL service performs internal processing to achieve the next target state.
stateDiagram-v2
direction LR
[*] --> UNKNOWN
UNKNOWN --> CLOSED: <init>
CLOSED --> OPENING: open()
OPENING --> READY: success
OPENING --> CLOSED: <error>
READY --> STARTING: start()
STARTING --> READY: <error>
STARTING --> STARTED: success
STARTED --> FLUSHING: flush()
FLUSHING --> STARTED: success
STARTED --> STOPPING: stop()
STOPPING --> READY: success
READY --> CLOSING: close()
CLOSING --> CLOSED: success
classDef NonTransitory fill:#1976D2, color:white, font-weight:bold;
classDef Transitory fill:#90CAF9, color:black, font-weight:bold;
class CLOSED,READY,STARTED NonTransitory
class UNKNOWN,OPENING,CLOSING,STARTING,STOPPING,FLUSHING Transitory
State Change Callbacks Sequence
The sequence diagram below shows the typical behaviour of the state machine and the expected callbacks.
Many HAL services allow for multiple callback listeners to be registered and each registered listener would be notified of the state changes.
sequenceDiagram
box rgb(30,136,229) Client Component
participant Client as Client to <br>HAL service
participant Listener as Callback Listener
end
box rgb(249,168,37) HAL Component
participant HAL as HAL Service
end
Client->>HAL: registerEventListener(... callback listener...)
Note over HAL: open() transitions from CLOSED -> OPENING -> READY
Client->>HAL: open()
HAL-->>Listener: onStateChanged(CLOSED -> OPENING)
HAL-->>Listener: onStateChanged(OPENING -> READY)
Note over HAL: start() transitions from READY -> STARTING -> STARTED
Client->>HAL: start()
HAL-->>Listener: onStateChanged(READY -> STARTING)
HAL-->>Listener: onStateChanged(STARTING -> STARTED)
Note over HAL: flush() transitions from STARTED -> FLUSHING -> STARTED
Client->>HAL: flush()
HAL-->>Listener: onStateChanged(STARTED -> FLUSHING)
HAL-->>Listener: onStateChanged(FLUSHING -> STARTED)
Note over HAL: stop() transitions from STARTED -> STOPPING -> STOPPED
Client->>HAL: stop()
HAL-->>Listener: onStateChanged(STARTED -> STOPPING)
Note over HAL: A flush is also implied by stop().
HAL-->>Listener: onStateChanged(STOPPING -> READY)
Note over HAL: stop() transitions from READY -> CLOSING -> CLOSED
Client->>HAL: close()
HAL-->>Listener: onStateChanged(READY -> CLOSING)
HAL-->>Listener: onStateChanged(CLOSING -> CLOSED)
Note over HAL: Errors during open() transitions from CLOSED -> OPENING -> CLOSED
Client->>HAL: open()
HAL-->>Listener: onStateChanged(CLOSED -> OPENING)
HAL-->>Listener: onStateChanged(OPENING -> CLOSED)
Client->>HAL: unregisterEventListener(... callback listener...)