Skip to content

Extension Points

FlowActionHandler and FlowStateListener are the two classes that let the client code inject its own logic into the onboarding process. They have the same concept and purposes as the view-based flows component. This section discusses the differences.


Provide Custom Steps

    open fun getFlowCustomizationSteps(flow: BaseFlow, insertionPoint: CustomStepInsertionPoint) = Unit

Because Fragment is not used in the Jetpack compose world, the way to provide custom steps for the onboarding flow is also different. The preceding code is the signature of the function in FlowActionHandler that you can override to add custom steps. The flow argument is the running flow instance, and insertionPoint is the insertion point currently supported in the compose version of the flows component. Here is an example:

    override fun getFlowCustomizationSteps(
        flow: BaseFlow,
        insertionPoint: CustomStepInsertionPoint
    ) {
        if (flow.flowName == {
            when (insertionPoint) {
                CustomStepInsertionPoint.BeforeEula -> {
                    flow.addSingleStep(step_welcome, secure = false) {
                            primaryViewClickListener = {
                            secondaryViewClickListener = {
                else -> Unit

The preceding sample code adds a welcome step before the EULA step for the onboarding flow. Currently, we provide the following insertion points in the SDK:

sealed class CustomStepInsertionPoint {
    object BeforeEula : CustomStepInsertionPoint()
    object BeforeActivation : CustomStepInsertionPoint()
    object BeforeAuthentication : CustomStepInsertionPoint()
    object BeforeSetPasscode : CustomStepInsertionPoint()
    object BeforeConsents : CustomStepInsertionPoint()
    object BeforeOnboardingFinish : CustomStepInsertionPoint()

Activation From MDM

open suspend fun activateFromManagedConfig(bundle: Bundle): AppConfig? = null

In the view-based flows component, the same function in FlowActionHandler has a default implementation that will try to read the application configuration from a predefined property. For the compose version, the logic is handled completely by the client code because the former method is too constrained and not flexible.


FlowStateListener has the same purpose as that in the view-based flows component and the sequence of the callback functions is also the same. So if you're migrating your existing project from the view-based flows to the compose version, you don't need to worry about the existing logic in your FlowStateListener.

Unlike the view-based flows component, now every callback function is marked as suspend, so it's easier for the client code to call other suspend functions.

Last update: February 20, 2023