• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2023 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 
18 package com.android.systemui.keyguard.domain.interactor
19 
20 import com.android.app.tracing.coroutines.launchTraced as launch
21 import com.android.systemui.CoreStartable
22 import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
23 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
24 import com.android.systemui.dagger.SysUISingleton
25 import com.android.systemui.dagger.qualifiers.Application
26 import com.android.systemui.keyguard.data.repository.KeyguardBlueprintRepository
27 import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
28 import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBlueprint
29 import com.android.systemui.keyguard.ui.view.layout.blueprints.SplitShadeKeyguardBlueprint
30 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config
31 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Type
32 import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection
33 import com.android.systemui.scene.shared.flag.SceneContainerFlag
34 import com.android.systemui.shade.ShadeDisplayAware
35 import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
36 import javax.inject.Inject
37 import kotlinx.coroutines.CoroutineScope
38 import kotlinx.coroutines.flow.StateFlow
39 import kotlinx.coroutines.flow.filter
40 import kotlinx.coroutines.flow.map
41 
42 @SysUISingleton
43 class KeyguardBlueprintInteractor
44 @Inject
45 constructor(
46     private val keyguardBlueprintRepository: KeyguardBlueprintRepository,
47     @Application private val applicationScope: CoroutineScope,
48     shadeModeInteractor: ShadeModeInteractor,
49     @ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
50     private val fingerprintPropertyInteractor: FingerprintPropertyInteractor,
51     private val smartspaceSection: SmartspaceSection,
52 ) : CoreStartable {
53     /** The current blueprint for the lockscreen. */
54     val blueprint: StateFlow<KeyguardBlueprint> = keyguardBlueprintRepository.blueprint
55 
56     /**
57      * Triggered when the blueprint isn't changed, but the ConstraintSet should be rebuilt and
58      * optionally a transition should be fired to move to the rebuilt ConstraintSet.
59      */
60     val refreshTransition = keyguardBlueprintRepository.refreshTransition
61 
62     /** Current BlueprintId */
63     val blueprintId =
64         shadeModeInteractor.isShadeLayoutWide.map { isShadeLayoutWide ->
65             val useSplitShade = isShadeLayoutWide && !SceneContainerFlag.isEnabled
66             when {
67                 useSplitShade -> SplitShadeKeyguardBlueprint.ID
68                 else -> DefaultKeyguardBlueprint.DEFAULT
69             }
70         }
71 
72     override fun start() {
73         applicationScope.launch { blueprintId.collect { transitionToBlueprint(it) } }
74         applicationScope.launch {
75             fingerprintPropertyInteractor.propertiesInitialized
76                 .filter { it }
77                 .collect { refreshBlueprint() }
78         }
79         applicationScope.launch {
80             val refreshConfig =
81                 Config(Type.NoTransition, rebuildSections = listOf(smartspaceSection))
82             configurationInteractor.onAnyConfigurationChange.collect {
83                 refreshBlueprint(refreshConfig)
84             }
85         }
86     }
87 
88     /**
89      * Transitions to a blueprint, or refreshes it if already applied.
90      *
91      * @param blueprintId
92      * @return whether the transition has succeeded.
93      */
94     fun transitionOrRefreshBlueprint(blueprintId: String): Boolean {
95         if (blueprintId == blueprint.value.id) {
96             refreshBlueprint()
97             return true
98         }
99 
100         return keyguardBlueprintRepository.applyBlueprint(blueprintId)
101     }
102 
103     /**
104      * Transitions to a blueprint.
105      *
106      * @param blueprintId
107      * @return whether the transition has succeeded.
108      */
109     fun transitionToBlueprint(blueprintId: String): Boolean {
110         return keyguardBlueprintRepository.applyBlueprint(blueprintId)
111     }
112 
113     /** Emits a value to refresh the blueprint with the appropriate transition. */
114     fun refreshBlueprint(type: Type = Type.NoTransition) = refreshBlueprint(Config(type))
115 
116     /** Emits a value to refresh the blueprint with the appropriate transition. */
117     fun refreshBlueprint(config: Config) = keyguardBlueprintRepository.refreshBlueprint(config)
118 
119     fun getCurrentBlueprint(): KeyguardBlueprint {
120         return keyguardBlueprintRepository.blueprint.value
121     }
122 
123     companion object {
124         private val TAG = "KeyguardBlueprintInteractor"
125     }
126 }
127