Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ae50aeba authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Android (Google) Code Review
Browse files

Merge "Don't handle interruptions too aggressively" into main

parents 6fb073e4 83bc9c36
Loading
Loading
Loading
Loading
+38 −77
Original line number Original line Diff line number Diff line
@@ -371,96 +371,57 @@ private fun prepareInterruption(
    transition: TransitionState.Transition,
    transition: TransitionState.Transition,
    previousTransition: TransitionState.Transition,
    previousTransition: TransitionState.Transition,
) {
) {
    val previousUniqueState = reconcileStates(element, previousTransition)
    val sceneStates = element.sceneStates
    if (previousUniqueState == null) {
    sceneStates[previousTransition.fromScene]?.selfUpdateValuesBeforeInterruption()
        reconcileStates(element, transition)
    sceneStates[previousTransition.toScene]?.selfUpdateValuesBeforeInterruption()
        return
    sceneStates[transition.fromScene]?.selfUpdateValuesBeforeInterruption()
    }
    sceneStates[transition.toScene]?.selfUpdateValuesBeforeInterruption()

    val fromSceneState = element.sceneStates[transition.fromScene]
    val toSceneState = element.sceneStates[transition.toScene]


    if (
    reconcileStates(element, previousTransition)
        fromSceneState == null ||
    reconcileStates(element, transition)
            toSceneState == null ||
            sharedElementTransformation(element.key, transition)?.enabled != false
    ) {
        // If there is only one copy of the element or if the element is shared, animate deltas in
        // both scenes.
        fromSceneState?.updateValuesBeforeInterruption(previousUniqueState)
        toSceneState?.updateValuesBeforeInterruption(previousUniqueState)
    }
}
}


/**
/**
 * Reconcile the state of [element] in the fromScene and toScene of [transition] so that the values
 * Reconcile the state of [element] in the fromScene and toScene of [transition] so that the values
 * before interruption have their expected values, taking shared transitions into account.
 * before interruption have their expected values, taking shared transitions into account.
 *
 * If the element had a unique state, i.e. it is shared in [transition] or it is only present in one
 * of the scenes, return it.
 */
 */
private fun reconcileStates(
private fun reconcileStates(
    element: Element,
    element: Element,
    transition: TransitionState.Transition,
    transition: TransitionState.Transition,
): Element.SceneState? {
) {
    val fromSceneState = element.sceneStates[transition.fromScene]
    val fromSceneState = element.sceneStates[transition.fromScene] ?: return
    val toSceneState = element.sceneStates[transition.toScene]
    val toSceneState = element.sceneStates[transition.toScene] ?: return
    when {
    if (!isSharedElementEnabled(element.key, transition)) {
        // Element is in both scenes.
        return
        fromSceneState != null && toSceneState != null -> {
            val isSharedTransformationDisabled =
                sharedElementTransformation(element.key, transition)?.enabled == false
            when {
                // Element shared transition is disabled so the element is placed in both scenes.
                isSharedTransformationDisabled -> {
                    fromSceneState.updateValuesBeforeInterruption(fromSceneState)
                    toSceneState.updateValuesBeforeInterruption(toSceneState)
                    return null
    }
    }


    if (
        fromSceneState.offsetBeforeInterruption != Offset.Unspecified &&
            toSceneState.offsetBeforeInterruption == Offset.Unspecified
    ) {
        // Element is shared and placed in fromScene only.
        // Element is shared and placed in fromScene only.
                fromSceneState.lastOffset != Offset.Unspecified -> {
                    fromSceneState.updateValuesBeforeInterruption(fromSceneState)
        toSceneState.updateValuesBeforeInterruption(fromSceneState)
        toSceneState.updateValuesBeforeInterruption(fromSceneState)
                    return fromSceneState
    } else if (
                }
        toSceneState.offsetBeforeInterruption != Offset.Unspecified &&

            fromSceneState.offsetBeforeInterruption == Offset.Unspecified
    ) {
        // Element is shared and placed in toScene only.
        // Element is shared and placed in toScene only.
                toSceneState.lastOffset != Offset.Unspecified -> {
        fromSceneState.updateValuesBeforeInterruption(toSceneState)
        fromSceneState.updateValuesBeforeInterruption(toSceneState)
                    toSceneState.updateValuesBeforeInterruption(toSceneState)
                    return toSceneState
                }

                // Element is in none of the scenes.
                else -> {
                    fromSceneState.updateValuesBeforeInterruption(null)
                    toSceneState.updateValuesBeforeInterruption(null)
                    return null
                }
            }
    }
    }

        // Element is only in fromScene.
        fromSceneState != null -> {
            fromSceneState.updateValuesBeforeInterruption(fromSceneState)
            return fromSceneState
}
}


        // Element is only in toScene.
private fun Element.SceneState.selfUpdateValuesBeforeInterruption() {
        toSceneState != null -> {
    offsetBeforeInterruption = lastOffset
            toSceneState.updateValuesBeforeInterruption(toSceneState)
    sizeBeforeInterruption = lastSize
            return toSceneState
    scaleBeforeInterruption = lastScale
        }
    alphaBeforeInterruption = lastAlpha
        else -> return null
    }
}
}


private fun Element.SceneState.updateValuesBeforeInterruption(lastState: Element.SceneState?) {
private fun Element.SceneState.updateValuesBeforeInterruption(lastState: Element.SceneState) {
    offsetBeforeInterruption = lastState?.lastOffset ?: Offset.Unspecified
    offsetBeforeInterruption = lastState.offsetBeforeInterruption
    sizeBeforeInterruption = lastState?.lastSize ?: Element.SizeUnspecified
    sizeBeforeInterruption = lastState.sizeBeforeInterruption
    scaleBeforeInterruption = lastState?.lastScale ?: Scale.Unspecified
    scaleBeforeInterruption = lastState.scaleBeforeInterruption
    alphaBeforeInterruption = lastState?.lastAlpha ?: Element.AlphaUnspecified
    alphaBeforeInterruption = lastState.alphaBeforeInterruption


    clearInterruptionDeltas()
    clearInterruptionDeltas()
}
}