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