1 /*
2  * 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.brightness.ui.viewmodel
18 
19 import com.android.systemui.brightness.domain.interactor.BrightnessPolicyEnforcementInteractor
20 import com.android.systemui.brightness.domain.interactor.ScreenBrightnessInteractor
21 import com.android.systemui.brightness.shared.model.GammaBrightness
22 import com.android.systemui.common.shared.model.ContentDescription
23 import com.android.systemui.common.shared.model.Icon
24 import com.android.systemui.common.shared.model.Text
25 import com.android.systemui.dagger.SysUISingleton
26 import com.android.systemui.dagger.qualifiers.Application
27 import com.android.systemui.res.R
28 import com.android.systemui.utils.PolicyRestriction
29 import javax.inject.Inject
30 import kotlinx.coroutines.CoroutineScope
31 import kotlinx.coroutines.flow.SharingStarted
32 import kotlinx.coroutines.flow.stateIn
33 
34 @SysUISingleton
35 class BrightnessSliderViewModel
36 @Inject
37 constructor(
38     private val screenBrightnessInteractor: ScreenBrightnessInteractor,
39     private val brightnessPolicyEnforcementInteractor: BrightnessPolicyEnforcementInteractor,
40     @Application private val applicationScope: CoroutineScope,
41 ) {
42     val currentBrightness =
43         screenBrightnessInteractor.gammaBrightness.stateIn(
44             applicationScope,
45             SharingStarted.WhileSubscribed(),
46             GammaBrightness(0)
47         )
48 
49     val maxBrightness = screenBrightnessInteractor.maxGammaBrightness
50     val minBrightness = screenBrightnessInteractor.minGammaBrightness
51 
52     val label = Text.Resource(R.string.quick_settings_brightness_dialog_title)
53 
54     val icon = Icon.Resource(R.drawable.ic_brightness_full, ContentDescription.Resource(label.res))
55 
56     val policyRestriction = brightnessPolicyEnforcementInteractor.brightnessPolicyRestriction
57 
showPolicyRestrictionDialognull58     fun showPolicyRestrictionDialog(restriction: PolicyRestriction.Restricted) {
59         brightnessPolicyEnforcementInteractor.startAdminSupportDetailsDialog(restriction)
60     }
61 
62     /**
63      * As a brightness slider is dragged, the corresponding events should be sent using this method.
64      */
onDragnull65     suspend fun onDrag(drag: Drag) {
66         when (drag) {
67             is Drag.Dragging -> screenBrightnessInteractor.setTemporaryBrightness(drag.brightness)
68             is Drag.Stopped -> screenBrightnessInteractor.setBrightness(drag.brightness)
69         }
70     }
71 
72     /**
73      * Format the current value of brightness as a percentage between the minimum and maximum gamma.
74      */
formatValuenull75     fun formatValue(value: Int): String {
76         val min = minBrightness.value
77         val max = maxBrightness.value
78         val coercedValue = value.coerceIn(min, max)
79         val percentage = (coercedValue - min) * 100 / (max - min)
80         // This is not finalized UI so using fixed string
81         return "$percentage%"
82     }
83 }
84 
85 /** Represents a drag event in a brightness slider. */
86 sealed interface Drag {
87     val brightness: GammaBrightness
88     @JvmInline value class Dragging(override val brightness: GammaBrightness) : Drag
89     @JvmInline value class Stopped(override val brightness: GammaBrightness) : Drag
90 }
91