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

Commit ee335b20 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Enable and configure interruptions in Flexiglass

This CL enables interruptions in Flexiglass and configures the most
common interruptions that happen when face authentication kicks in while
we were transition from one scene to Bouncer.

Enabling this flag will also to have multiple transitions to happen in
parallel, which is going to be more and more important with overlays and
once we have scenes with horizontal swipes like Communal.

See b/290184746#comment13 for details and before/after videos.

Bug: 290184746
Test: Manual, see b/290184746#comment13. Unfortunately motion tests are
 not configured for a full Flexiglass set up yet so I can't unit test
 it.
Flag: com.android.systemui.scene_container
Change-Id: Ia4fd64162d8930dcd091c6616ff219a58eeae4e3
parent 19719a16
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -81,7 +81,6 @@ fun SceneContainer(
            initialScene = initialSceneKey,
            canChangeScene = { toScene -> viewModel.canChangeScene(toScene) },
            transitions = SceneContainerTransitions,
            enableInterruptions = false,
        )
    }

+72 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.scene.ui.composable

import com.android.compose.animation.scene.InterruptionHandler
import com.android.compose.animation.scene.InterruptionResult
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION

object SceneContainerInterruptionHandler : InterruptionHandler {
    override fun onInterruption(
        interrupted: TransitionState.Transition.ChangeScene,
        newTargetScene: SceneKey,
    ): InterruptionResult? {
        return handleTransitionToGoneDuringTransitionToBouncer(interrupted, newTargetScene)
    }

    /**
     * Handle the case where we start transitioning to Bouncer but then we are interrupted to
     * transition to Gone, for instance because face auth kicked in.
     */
    private fun handleTransitionToGoneDuringTransitionToBouncer(
        transition: TransitionState.Transition.ChangeScene,
        targetScene: SceneKey,
    ): InterruptionResult? {
        if (targetScene != Scenes.Gone || !transition.isTransitioningFromOrTo(Scenes.Bouncer)) {
            return null
        }

        // Animate Bouncer => Gone only when the bouncer is fully opaque, otherwise animate
        // OtherScene => Gone and reverse the OtherScene => Bouncer transition (note: OtherScene is
        // usually the Lockscreen scene).
        val otherScene: SceneKey
        val animatesFromBouncer =
            if (transition.isTransitioning(to = Scenes.Bouncer)) {
                otherScene = transition.fromScene
                transition.progress >= TO_BOUNCER_FADE_FRACTION
            } else {
                otherScene = transition.toScene
                transition.progress <= 1f - TO_BOUNCER_FADE_FRACTION
            }

        return if (animatesFromBouncer) {
            InterruptionResult(
                animateFrom = Scenes.Bouncer,

                // We don't want the content of the lockscreen to be shown during the Bouncer =>
                // Launcher transition. We disable chaining of the transitions so that only the
                // Bouncer and Launcher scenes are composed.
                chain = false,
            )
        } else {
            InterruptionResult(animateFrom = otherScene)
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.systemui.shade.ui.composable.Shade
 * Please keep the list sorted alphabetically.
 */
val SceneContainerTransitions = transitions {
    interruptionHandler = SceneContainerInterruptionHandler

    // Overscroll progress starts linearly with some resistance (3f) and slowly approaches 0.2f
    defaultOverscrollProgressConverter = ProgressConverter.tanh(maxProgress = 0.2f, tilt = 3f)