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.keyguard.domain.interactor.KeyguardInteractor 22 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor 23 import com.android.systemui.keyguard.shared.model.KeyguardState 24 import com.android.systemui.res.R 25 import com.android.systemui.shade.ShadeDisplayAware 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 @ShadeDisplayAware 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(shadeInteractor.isShadeTouchable, keyguardInteractor.isKeyguardVisible) { 55 panelTouchesEnabled, 56 isKeyguardVisible -> 57 panelTouchesEnabled && isKeyguardVisible 58 } 59 .flowOn(bgContext) 60 .conflate() 61 .distinctUntilChanged() 62 63 /** Amount of a "white" tint to be applied to the icons. */ 64 val tintAlpha: Flow<Float> = 65 combine( 66 keyguardTransitionInteractor.transitionValue(KeyguardState.AOD).onStart { 67 emit(0f) 68 }, 69 keyguardTransitionInteractor.transitionValue(KeyguardState.DOZING).onStart { 70 emit(0f) 71 }, 72 ) { aodAmt, dozeAmt -> 73 aodAmt + dozeAmt // If transitioning between them, they should sum to 1f 74 } 75 .flowOn(bgContext) 76 .conflate() 77 .distinctUntilChanged() 78 79 /** Are notification icons animated (ex: animated gif)? */ 80 val areIconAnimationsEnabled: Flow<Boolean> = 81 keyguardTransitionInteractor 82 .isFinishedInStateWhere { 83 // Don't animate icons when we're on AOD / dozing 84 it != KeyguardState.AOD && it != KeyguardState.DOZING 85 } 86 .onStart { emit(true) } 87 .flowOn(bgContext) 88 .conflate() 89 .distinctUntilChanged() 90 91 /** [NotificationIconsViewData] indicating which icons to display in the view. */ 92 val icons: Flow<NotificationIconsViewData> = 93 iconsInteractor.aodNotifs 94 .map { entries -> 95 NotificationIconsViewData( 96 visibleIcons = entries.mapNotNull { it.toIconInfo(it.aodIcon) }, 97 iconLimit = maxIcons, 98 ) 99 } 100 .flowOn(bgContext) 101 .conflate() 102 .distinctUntilChanged() 103 } 104