1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.systemui.scene.data.repository
18
19 import com.android.compose.animation.scene.ObservableTransitionState
20 import com.android.compose.animation.scene.SceneKey
21 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
22 import com.android.systemui.keyguard.shared.model.KeyguardState
23 import com.android.systemui.keyguard.shared.model.TransitionStep
24 import com.android.systemui.kosmos.Kosmos
25 import com.android.systemui.kosmos.testScope
26 import com.android.systemui.scene.shared.flag.SceneContainerFlag
27 import com.android.systemui.scene.shared.model.Scenes
28 import kotlinx.coroutines.flow.Flow
29 import kotlinx.coroutines.flow.MutableStateFlow
30 import kotlinx.coroutines.flow.flowOf
31 import kotlinx.coroutines.test.TestScope
32
33 private val mutableTransitionState =
34 MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(Scenes.Lockscreen))
35
setTransitionnull36 suspend fun Kosmos.setTransition(
37 sceneTransition: ObservableTransitionState,
38 stateTransition: TransitionStep? = null,
39 fillInStateSteps: Boolean = true,
40 scope: TestScope = testScope,
41 repository: SceneContainerRepository = sceneContainerRepository
42 ) {
43 var state: TransitionStep? = stateTransition
44 if (SceneContainerFlag.isEnabled) {
45 setSceneTransition(sceneTransition, scope, repository)
46
47 if (state != null) {
48 state = getStateWithUndefined(sceneTransition, state)
49 }
50 }
51
52 if (state == null) return
53 fakeKeyguardTransitionRepository.sendTransitionSteps(
54 step = state,
55 testScope = scope,
56 fillInSteps = fillInStateSteps,
57 )
58 scope.testScheduler.runCurrent()
59 }
60
setSceneTransitionnull61 fun Kosmos.setSceneTransition(
62 transition: ObservableTransitionState,
63 scope: TestScope = testScope,
64 repository: SceneContainerRepository = sceneContainerRepository
65 ) {
66 repository.setTransitionState(mutableTransitionState)
67 mutableTransitionState.value = transition
68 scope.testScheduler.runCurrent()
69 }
70
Transitionnull71 fun Transition(
72 from: SceneKey,
73 to: SceneKey,
74 currentScene: Flow<SceneKey> = flowOf(to),
75 progress: Flow<Float> = flowOf(0f),
76 isInitiatedByUserInput: Boolean = false,
77 isUserInputOngoing: Flow<Boolean> = flowOf(false),
78 previewProgress: Flow<Float> = flowOf(0f),
79 isInPreviewStage: Flow<Boolean> = flowOf(false)
80 ): ObservableTransitionState.Transition {
81 return ObservableTransitionState.Transition(
82 fromScene = from,
83 toScene = to,
84 currentScene = currentScene,
85 progress = progress,
86 isInitiatedByUserInput = isInitiatedByUserInput,
87 isUserInputOngoing = isUserInputOngoing,
88 previewProgress = previewProgress,
89 isInPreviewStage = isInPreviewStage
90 )
91 }
92
Idlenull93 fun Idle(currentScene: SceneKey): ObservableTransitionState.Idle {
94 return ObservableTransitionState.Idle(currentScene)
95 }
96
getStateWithUndefinednull97 private fun getStateWithUndefined(
98 sceneTransition: ObservableTransitionState,
99 state: TransitionStep
100 ): TransitionStep {
101 return when (sceneTransition) {
102 is ObservableTransitionState.Idle -> {
103 TransitionStep(
104 from = state.from,
105 to =
106 if (sceneTransition.currentScene != Scenes.Lockscreen) {
107 KeyguardState.UNDEFINED
108 } else {
109 state.to
110 },
111 value = state.value,
112 transitionState = state.transitionState
113 )
114 }
115 is ObservableTransitionState.Transition -> {
116 TransitionStep(
117 from =
118 if (sceneTransition.fromContent != Scenes.Lockscreen) {
119 KeyguardState.UNDEFINED
120 } else {
121 state.from
122 },
123 to =
124 if (sceneTransition.toContent != Scenes.Lockscreen) {
125 KeyguardState.UNDEFINED
126 } else {
127 state.from
128 },
129 value = state.value,
130 transitionState = state.transitionState
131 )
132 }
133 else -> state
134 }
135 }
136