• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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