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 package com.android.systemui.statusbar.notification.icon.ui.viewmodel 17 18 import android.content.res.Resources 19 import com.android.systemui.dagger.SysUISingleton 20 import com.android.systemui.dagger.qualifiers.Background 21 import com.android.systemui.dagger.qualifiers.Main 22 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor 23 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor 24 import com.android.systemui.keyguard.shared.model.KeyguardState 25 import com.android.systemui.res.R 26 import com.android.systemui.shade.domain.interactor.ShadeInteractor 27 import com.android.systemui.statusbar.notification.icon.domain.interactor.AlwaysOnDisplayNotificationIconsInteractor 28 import javax.inject.Inject 29 import kotlin.coroutines.CoroutineContext 30 import kotlinx.coroutines.flow.Flow 31 import kotlinx.coroutines.flow.combine 32 import kotlinx.coroutines.flow.conflate 33 import kotlinx.coroutines.flow.distinctUntilChanged 34 import kotlinx.coroutines.flow.flowOn 35 import kotlinx.coroutines.flow.map 36 import kotlinx.coroutines.flow.onStart 37 38 /** View-model for the row of notification icons displayed on the always-on display. */ 39 @SysUISingleton 40 class NotificationIconContainerAlwaysOnDisplayViewModel 41 @Inject 42 constructor( 43 @Background bgContext: CoroutineContext, 44 iconsInteractor: AlwaysOnDisplayNotificationIconsInteractor, 45 keyguardInteractor: KeyguardInteractor, 46 keyguardTransitionInteractor: KeyguardTransitionInteractor, 47 @Main resources: Resources, 48 shadeInteractor: ShadeInteractor, 49 ) { 50 private val maxIcons = resources.getInteger(R.integer.max_notif_icons_on_aod) 51 52 /** Are changes to the icon container animated? */ 53 val areContainerChangesAnimated: Flow<Boolean> = 54 combine( 55 shadeInteractor.isShadeTouchable, 56 keyguardInteractor.isKeyguardVisible, 57 ) { panelTouchesEnabled, isKeyguardVisible -> 58 panelTouchesEnabled && isKeyguardVisible 59 } 60 .flowOn(bgContext) 61 .conflate() 62 .distinctUntilChanged() 63 64 /** Amount of a "white" tint to be applied to the icons. */ 65 val tintAlpha: Flow<Float> = 66 combine( 67 keyguardTransitionInteractor.transitionValue(KeyguardState.AOD).onStart { 68 emit(0f) 69 }, 70 keyguardTransitionInteractor.transitionValue(KeyguardState.DOZING).onStart { 71 emit(0f) 72 }, 73 ) { aodAmt, dozeAmt -> 74 aodAmt + dozeAmt // If transitioning between them, they should sum to 1f 75 } 76 .flowOn(bgContext) 77 .conflate() 78 .distinctUntilChanged() 79 80 /** Are notification icons animated (ex: animated gif)? */ 81 val areIconAnimationsEnabled: Flow<Boolean> = 82 keyguardTransitionInteractor 83 .isFinishedInStateWhere { 84 // Don't animate icons when we're on AOD / dozing 85 it != KeyguardState.AOD && it != KeyguardState.DOZING 86 } 87 .onStart { emit(true) } 88 .flowOn(bgContext) 89 .conflate() 90 .distinctUntilChanged() 91 92 /** [NotificationIconsViewData] indicating which icons to display in the view. */ 93 val icons: Flow<NotificationIconsViewData> = 94 iconsInteractor.aodNotifs 95 .map { entries -> 96 NotificationIconsViewData( 97 visibleIcons = entries.mapNotNull { it.toIconInfo(it.aodIcon) }, 98 iconLimit = maxIcons, 99 ) 100 } 101 .flowOn(bgContext) 102 .conflate() 103 .distinctUntilChanged() 104 } 105