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.brightness.domain.interactor
18 
19 import com.android.settingslib.display.BrightnessUtils
20 import com.android.systemui.brightness.data.repository.ScreenBrightnessRepository
21 import com.android.systemui.brightness.shared.model.BrightnessLog
22 import com.android.systemui.brightness.shared.model.GammaBrightness
23 import com.android.systemui.brightness.shared.model.LinearBrightness
24 import com.android.systemui.brightness.shared.model.logDiffForTable
25 import com.android.systemui.dagger.SysUISingleton
26 import com.android.systemui.dagger.qualifiers.Application
27 import com.android.systemui.log.table.TableLogBuffer
28 import javax.inject.Inject
29 import kotlinx.coroutines.CoroutineScope
30 import kotlinx.coroutines.flow.Flow
31 import kotlinx.coroutines.flow.SharingStarted
32 import kotlinx.coroutines.flow.combine
33 import kotlinx.coroutines.flow.stateIn
34 
35 /**
36  * Converts between [GammaBrightness] and [LinearBrightness].
37  *
38  * @see BrightnessUtils
39  */
40 @SysUISingleton
41 class ScreenBrightnessInteractor
42 @Inject
43 constructor(
44     private val screenBrightnessRepository: ScreenBrightnessRepository,
45     @Application private val applicationScope: CoroutineScope,
46     @BrightnessLog private val tableBuffer: TableLogBuffer,
47 ) {
48     /** Maximum value in the Gamma space for brightness */
49     val maxGammaBrightness = GammaBrightness(BrightnessUtils.GAMMA_SPACE_MAX)
50 
51     /** Minimum value in the Gamma space for brightness */
52     val minGammaBrightness = GammaBrightness(BrightnessUtils.GAMMA_SPACE_MIN)
53 
54     /**
55      * Brightness in the Gamma space for the current display. It will always represent a value
56      * between [minGammaBrightness] and [maxGammaBrightness]
57      */
58     val gammaBrightness: Flow<GammaBrightness> =
59         with(screenBrightnessRepository) {
60             combine(
61                     linearBrightness,
62                     minLinearBrightness,
63                     maxLinearBrightness,
64                 ) { brightness, min, max ->
65                     brightness.toGammaBrightness(min, max)
66                 }
67                 .logDiffForTable(tableBuffer, TABLE_PREFIX_GAMMA, TABLE_COLUMN_BRIGHTNESS, null)
68                 .stateIn(applicationScope, SharingStarted.WhileSubscribed(), GammaBrightness(0))
69         }
70 
71     /** Sets the brightness temporarily, while the user is changing it. */
72     suspend fun setTemporaryBrightness(gammaBrightness: GammaBrightness) {
73         screenBrightnessRepository.setTemporaryBrightness(
74             gammaBrightness.clamp().toLinearBrightness()
75         )
76     }
77 
78     /** Sets the brightness definitely. */
79     suspend fun setBrightness(gammaBrightness: GammaBrightness) {
80         screenBrightnessRepository.setBrightness(gammaBrightness.clamp().toLinearBrightness())
81     }
82 
83     private suspend fun GammaBrightness.toLinearBrightness(): LinearBrightness {
84         val bounds = screenBrightnessRepository.getMinMaxLinearBrightness()
85         return LinearBrightness(
86             BrightnessUtils.convertGammaToLinearFloat(
87                 value,
88                 bounds.first.floatValue,
89                 bounds.second.floatValue
90             )
91         )
92     }
93 
94     private fun GammaBrightness.clamp(): GammaBrightness {
95         return GammaBrightness(value.coerceIn(minGammaBrightness.value, maxGammaBrightness.value))
96     }
97 
98     private fun LinearBrightness.toGammaBrightness(
99         min: LinearBrightness,
100         max: LinearBrightness,
101     ): GammaBrightness {
102         return GammaBrightness(
103             BrightnessUtils.convertLinearToGammaFloat(floatValue, min.floatValue, max.floatValue)
104         )
105     }
106 
107     private companion object {
108         const val TABLE_COLUMN_BRIGHTNESS = "brightness"
109         const val TABLE_PREFIX_GAMMA = "gamma"
110     }
111 }
112