1 /* <lambda>null2 * Copyright (C) 2024 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.statusbar.notification.stack.ui.viewmodel 18 19 import androidx.compose.material3.MaterialTheme 20 import androidx.compose.runtime.Composable 21 import androidx.compose.runtime.ReadOnlyComposable 22 import androidx.compose.runtime.getValue 23 import androidx.compose.ui.graphics.Color 24 import androidx.compose.ui.res.colorResource 25 import com.android.app.tracing.coroutines.coroutineScopeTraced 26 import com.android.compose.animation.scene.ElementKey 27 import com.android.systemui.dump.DumpManager 28 import com.android.systemui.lifecycle.ExclusiveActivatable 29 import com.android.systemui.lifecycle.Hydrator 30 import com.android.systemui.notifications.ui.composable.Notifications 31 import com.android.systemui.res.R 32 import com.android.systemui.shade.domain.interactor.ShadeModeInteractor 33 import com.android.systemui.shade.shared.model.ShadeMode 34 import com.android.systemui.shade.ui.composable.Shade 35 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor 36 import com.android.systemui.util.kotlin.ActivatableFlowDumper 37 import com.android.systemui.util.kotlin.ActivatableFlowDumperImpl 38 import dagger.assisted.AssistedFactory 39 import dagger.assisted.AssistedInject 40 import kotlinx.coroutines.awaitCancellation 41 import kotlinx.coroutines.flow.StateFlow 42 import kotlinx.coroutines.flow.map 43 import kotlinx.coroutines.launch 44 45 class NotificationLockscreenScrimViewModel 46 @AssistedInject 47 constructor( 48 dumpManager: DumpManager, 49 shadeModeInteractor: ShadeModeInteractor, 50 private val stackAppearanceInteractor: NotificationStackAppearanceInteractor, 51 ) : 52 ActivatableFlowDumper by ActivatableFlowDumperImpl(dumpManager, "NotificationScrollViewModel"), 53 ExclusiveActivatable() { 54 55 private val hydrator = Hydrator("NotificationLockscreenScrimViewModel.hydrator") 56 57 val shadeMode: StateFlow<ShadeMode> = shadeModeInteractor.shadeMode 58 59 /** The [ElementKey] to use for the scrim. */ 60 val element: ElementViewModel by 61 hydrator.hydratedStateOf( 62 traceName = "elementKey", 63 initialValue = element(shadeMode.value), 64 source = shadeMode.map { element(it) }, 65 ) 66 67 /** Sets the alpha to apply to the NSSL for fade-in on lockscreen */ 68 fun setAlphaForLockscreenFadeIn(alpha: Float) { 69 stackAppearanceInteractor.setAlphaForLockscreenFadeIn(alpha) 70 } 71 72 override suspend fun onActivated(): Nothing { 73 coroutineScopeTraced("NotificationLockscreenScrimViewModel") { 74 launch { activateFlowDumper() } 75 launch { hydrator.activate() } 76 awaitCancellation() 77 } 78 } 79 80 private fun element(shadeMode: ShadeMode): ElementViewModel { 81 return if (shadeMode == ShadeMode.Single) { 82 ElementViewModel( 83 key = Notifications.Elements.NotificationScrim, 84 color = { SingleShadeBackground }, 85 ) 86 } else { 87 ElementViewModel( 88 key = Shade.Elements.BackgroundScrim, 89 color = { isBouncerToLockscreen -> 90 if (isBouncerToLockscreen) { 91 SplitShadeBouncerToLockscreenBackground 92 } else { 93 SplitShadeDefaultBackground 94 } 95 }, 96 ) 97 } 98 } 99 100 /** Models the UI state of the scrim. */ 101 data class ElementViewModel( 102 /** The [ElementKey] to use with an `element` modifier. */ 103 val key: ElementKey, 104 /** A function that returns the color to use within a `background` modifier. */ 105 val color: @Composable (isBouncerToLockscreen: Boolean) -> Color, 106 ) 107 108 @AssistedFactory 109 interface Factory { 110 fun create(): NotificationLockscreenScrimViewModel 111 } 112 113 companion object { 114 private val SingleShadeBackground: Color 115 @Composable @ReadOnlyComposable get() = MaterialTheme.colorScheme.surface 116 117 private val SplitShadeBouncerToLockscreenBackground: Color 118 @Composable @ReadOnlyComposable get() = MaterialTheme.colorScheme.surface 119 120 private val SplitShadeDefaultBackground: Color 121 @Composable 122 @ReadOnlyComposable 123 get() = colorResource(R.color.shade_scrim_background_dark) 124 } 125 } 126