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 android.content.res.Resources 20 import com.android.internal.annotations.VisibleForTesting 21 import com.android.systemui.biometrics.AuthController 22 import com.android.systemui.dagger.SysUISingleton 23 import com.android.systemui.dagger.qualifiers.Application 24 import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor 25 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor 26 import com.android.systemui.keyguard.shared.model.ClockSize 27 import com.android.systemui.res.R 28 import com.android.systemui.shade.domain.interactor.ShadeInteractor 29 import com.android.systemui.shade.shared.model.ShadeMode 30 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor 31 import javax.inject.Inject 32 import kotlinx.coroutines.CoroutineScope 33 import kotlinx.coroutines.flow.SharingStarted 34 import kotlinx.coroutines.flow.StateFlow 35 import kotlinx.coroutines.flow.combine 36 import kotlinx.coroutines.flow.distinctUntilChanged 37 import kotlinx.coroutines.flow.map 38 import kotlinx.coroutines.flow.stateIn 39 40 @SysUISingleton 41 class LockscreenContentViewModel 42 @Inject 43 constructor( 44 clockInteractor: KeyguardClockInteractor, 45 private val interactor: KeyguardBlueprintInteractor, 46 private val authController: AuthController, 47 val longPress: KeyguardLongPressViewModel, 48 val shadeInteractor: ShadeInteractor, 49 @Application private val applicationScope: CoroutineScope, 50 unfoldTransitionInteractor: UnfoldTransitionInteractor, 51 ) { 52 @VisibleForTesting val clockSize = clockInteractor.clockSize 53 54 val isUdfpsVisible: Boolean 55 get() = authController.isUdfpsSupported 56 57 val shouldUseSplitNotificationShade: StateFlow<Boolean> = 58 shadeInteractor.shadeMode 59 .map { it == ShadeMode.Split } 60 .stateIn( 61 scope = applicationScope, 62 started = SharingStarted.WhileSubscribed(), 63 initialValue = false, 64 ) 65 66 val areNotificationsVisible: StateFlow<Boolean> = 67 combine( 68 clockSize, 69 shouldUseSplitNotificationShade, 70 ) { clockSize, shouldUseSplitNotificationShade -> 71 clockSize == ClockSize.SMALL || shouldUseSplitNotificationShade 72 } 73 .stateIn( 74 scope = applicationScope, 75 started = SharingStarted.WhileSubscribed(), 76 initialValue = false, 77 ) 78 79 /** Amount of horizontal translation that should be applied to elements in the scene. */ 80 val unfoldTranslations: StateFlow<UnfoldTranslations> = 81 combine( 82 unfoldTransitionInteractor.unfoldTranslationX(isOnStartSide = true), 83 unfoldTransitionInteractor.unfoldTranslationX(isOnStartSide = false), 84 ) { start, end -> 85 UnfoldTranslations( 86 start = start, 87 end = end, 88 ) 89 } 90 .stateIn( 91 scope = applicationScope, 92 started = SharingStarted.WhileSubscribed(), 93 initialValue = UnfoldTranslations(), 94 ) 95 96 fun getSmartSpacePaddingTop(resources: Resources): Int { 97 return if (clockSize.value == ClockSize.LARGE) { 98 resources.getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) + 99 resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) 100 } else { 101 0 102 } 103 } 104 105 fun blueprintId(scope: CoroutineScope): StateFlow<String> { 106 return interactor.blueprint 107 .map { it.id } 108 .distinctUntilChanged() 109 .stateIn( 110 scope = scope, 111 started = SharingStarted.WhileSubscribed(), 112 initialValue = interactor.getCurrentBlueprint().id, 113 ) 114 } 115 116 data class UnfoldTranslations( 117 118 /** 119 * Amount of horizontal translation to apply to elements that are aligned to the start side 120 * (left in left-to-right layouts). Can also be used as horizontal padding for elements that 121 * need horizontal padding on both side. In pixels. 122 */ 123 val start: Float = 0f, 124 125 /** 126 * Amount of horizontal translation to apply to elements that are aligned to the end side 127 * (right in left-to-right layouts). In pixels. 128 */ 129 val end: Float = 0f, 130 ) 131 } 132