• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.keyguard.domain.interactor
18 
19 import android.animation.ValueAnimator
20 import android.util.Log
21 import com.android.systemui.Flags.transitionRaceCondition
22 import com.android.systemui.dagger.SysUISingleton
23 import com.android.systemui.dagger.qualifiers.Background
24 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
25 import com.android.systemui.keyguard.shared.model.KeyguardState
26 import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
27 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
28 import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
29 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
30 import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
31 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
32 import com.android.systemui.keyguard.shared.model.TransitionInfo
33 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
34 import com.android.systemui.scene.shared.flag.SceneContainerFlag
35 import javax.inject.Inject
36 import kotlinx.coroutines.CoroutineScope
37 import kotlinx.coroutines.launch
38 
39 @SysUISingleton
40 class KeyguardDismissTransitionInteractor
41 @Inject
42 constructor(
43     @Background private val scope: CoroutineScope,
44     private val repository: KeyguardTransitionRepository,
45     private val fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor,
46     private val fromPrimaryBouncerTransitionInteractor: FromPrimaryBouncerTransitionInteractor,
47     private val fromAodTransitionInteractor: FromAodTransitionInteractor,
48     private val fromAlternateBouncerTransitionInteractor: FromAlternateBouncerTransitionInteractor,
49     private val fromDozingTransitionInteractor: FromDozingTransitionInteractor,
50     private val fromOccludedTransitionInteractor: FromOccludedTransitionInteractor,
51 ) {
52 
53     /**
54      * Launches a coroutine to start a transition that will ultimately dismiss the keyguard from the
55      * current state.
56      *
57      * This is called exclusively by sources that can authoritatively say we should be unlocked,
58      * including KeyguardSecurityContainerController and WindowManager.
59      *
60      * This is one of the few transitions that is started outside of the From*TransitionInteractor
61      * classes. This is because this is an external call that must be respected, so it doesn't
62      * matter what state we're in/coming from - we must transition from that state to GONE.
63      *
64      * Invokes [onAlreadyGone] if the transition was not started because we're already GONE by the
65      * time the coroutine runs.
66      */
67     @JvmOverloads
startDismissKeyguardTransitionnull68     fun startDismissKeyguardTransition(reason: String = "", onAlreadyGone: (() -> Unit)? = null) {
69         if (SceneContainerFlag.isEnabled) return
70         Log.d(TAG, "#startDismissKeyguardTransition(reason=$reason)")
71 
72         scope.launch {
73             val startedState =
74                 if (transitionRaceCondition()) {
75                     repository.currentTransitionInfo.to
76                 } else {
77                     repository.currentTransitionInfoInternal.value.to
78                 }
79 
80             val animator: ValueAnimator? =
81                 when (startedState) {
82                     LOCKSCREEN -> fromLockscreenTransitionInteractor
83                     PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor
84                     ALTERNATE_BOUNCER -> fromAlternateBouncerTransitionInteractor
85                     AOD -> fromAodTransitionInteractor
86                     DOZING -> fromDozingTransitionInteractor
87                     OCCLUDED -> fromOccludedTransitionInteractor
88                     else -> null
89                 }?.getDefaultAnimatorForTransitionsToState(KeyguardState.GONE)
90 
91             if (startedState != KeyguardState.GONE && animator != null) {
92                 repository.startTransition(
93                     TransitionInfo(
94                         "KeyguardDismissTransitionInteractor" +
95                             if (reason.isNotBlank()) "($reason)" else "",
96                         startedState,
97                         KeyguardState.GONE,
98                         animator,
99                         TransitionModeOnCanceled.LAST_VALUE,
100                     )
101                 )
102             } else {
103                 Log.i(
104                     TAG,
105                     "Can't transition to GONE from $startedState; " +
106                         "ignoring startDismissKeyguardTransition.",
107                 )
108                 onAlreadyGone?.invoke()
109             }
110         }
111     }
112 
113     companion object {
114         private val TAG = KeyguardDismissTransitionInteractor::class.simpleName
115     }
116 }
117