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 package com.android.systemui.keyguard.ui.viewmodel 18 19 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor 20 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor 21 import com.android.systemui.dagger.qualifiers.Background 22 import com.android.systemui.dagger.qualifiers.Main 23 import com.android.systemui.doze.util.BurnInHelperWrapper 24 import com.android.systemui.keyguard.domain.interactor.BurnInInteractor 25 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor 26 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor 27 import com.android.systemui.keyguard.shared.model.BurnInModel 28 import com.android.systemui.keyguard.shared.model.KeyguardState 29 import com.android.systemui.keyguard.shared.model.StatusBarState 30 import com.android.systemui.res.R 31 import com.android.systemui.shade.ShadeDisplayAware 32 import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf 33 import javax.inject.Inject 34 import javax.inject.Named 35 import kotlinx.coroutines.CoroutineDispatcher 36 import kotlinx.coroutines.flow.Flow 37 import kotlinx.coroutines.flow.combine 38 import kotlinx.coroutines.flow.distinctUntilChanged 39 import kotlinx.coroutines.flow.flowOn 40 import kotlinx.coroutines.flow.map 41 42 /** View-model for the keyguard indication area view */ 43 class KeyguardIndicationAreaViewModel 44 @Inject 45 constructor( 46 private val keyguardInteractor: KeyguardInteractor, 47 private val burnInHelperWrapper: BurnInHelperWrapper, 48 burnInInteractor: BurnInInteractor, 49 @Named(KeyguardQuickAffordancesCombinedViewModelModule.Companion.LOCKSCREEN_INSTANCE) 50 shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, 51 @ShadeDisplayAware configurationInteractor: ConfigurationInteractor, 52 keyguardTransitionInteractor: KeyguardTransitionInteractor, 53 communalSceneInteractor: CommunalSceneInteractor, 54 @Background private val backgroundDispatcher: CoroutineDispatcher, 55 @Main private val mainDispatcher: CoroutineDispatcher, 56 ) { 57 58 /** Notifies when a new configuration is set */ 59 val configurationChange: Flow<Unit> = configurationInteractor.onAnyConfigurationChange 60 61 /** An observable for the visibility value for the indication area view. */ 62 val visible: Flow<Boolean> = 63 anyOf( 64 keyguardInteractor.statusBarState.map { state -> state == StatusBarState.KEYGUARD }, 65 communalSceneInteractor.isCommunalVisible, 66 ) 67 68 /** An observable for whether the indication area should be padded. */ 69 val isIndicationAreaPadded: Flow<Boolean> = 70 combine(shortcutsCombinedViewModel.startButton, shortcutsCombinedViewModel.endButton) { 71 startButtonModel, 72 endButtonModel -> 73 startButtonModel.isVisible || endButtonModel.isVisible 74 } 75 .distinctUntilChanged() 76 77 private val burnIn: Flow<BurnInModel> = 78 combine( 79 burnInInteractor.burnIn( 80 xDimenResourceId = R.dimen.burn_in_prevention_offset_x, 81 yDimenResourceId = R.dimen.default_burn_in_prevention_offset, 82 ), 83 keyguardTransitionInteractor.transitionValue(KeyguardState.AOD), 84 ) { burnIn, aodTransitionValue -> 85 BurnInModel( 86 (burnIn.translationX * aodTransitionValue).toInt(), 87 (burnIn.translationY * aodTransitionValue).toInt(), 88 burnIn.scale, 89 burnIn.scaleClockOnly, 90 ) 91 } 92 .distinctUntilChanged() 93 .flowOn(backgroundDispatcher) 94 95 /** An observable for the x-offset by which the indication area should be translated. */ 96 val indicationAreaTranslationX: Flow<Float> = 97 burnIn.map { it.translationX.toFloat() }.flowOn(mainDispatcher) 98 99 /** Returns an observable for the y-offset by which the indication area should be translated. */ 100 fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> { 101 return burnIn.map { it.translationY.toFloat() }.flowOn(mainDispatcher) 102 } 103 } 104