1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "calculation_manager.h"
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <iostream>
21 #include <sstream>
22 #include <string>
23 
24 #include "display_log.h"
25 
26 namespace OHOS {
27 namespace DisplayPowerMgr {
28 
29 namespace {
30 constexpr float DEFAULT_NO_OFFSET_LUX = -1.0f;
31 constexpr float DEFAULT_OFFSET_BRIGHTNESS = 0.0f;
32 constexpr float DEFAULT_OFFSET_DELTA = 0.0f;
33 constexpr float SMALL_VALUE = 1e-6f;
34 constexpr float DEFAULT_OFFSET_RATIO = 1.0f;
35 constexpr float MIN_OFFSET_RATIO = 0.0f;
36 constexpr float DEFAULT_MIN_DELTA = 1.0f;
37 constexpr float MIN_DEFAULT_BRIGHTNESS = 4.0f;
38 constexpr float MAX_DEFAULT_BRIGHTNESS = 255.0f;
39 
40 constexpr float AMBIENT_VALID_MAX_LUX = 40000;
41 constexpr float AMBIENT_VALID_MIN_LUX = 0.0f;
42 constexpr float DEFAULT_BRIGHTNESS = 100.0f;
43 }
44 
InitParameters()45 void BrightnessCalculationManager::InitParameters()
46 {
47     mBrightnessCalculationCurve.InitParameters();
48 }
49 
GetInterpolatedValue(float lux)50 float BrightnessCalculationManager::GetInterpolatedValue(float lux)
51 {
52     float valueInterp = GetInterpolatedBrightenssLevel(mPosBrightness, lux) / MAX_DEFAULT_BRIGHTNESS;
53     DISPLAY_HILOGI(FEAT_BRIGHTNESS, "GetInterpolatedValue lux=%{public}f, valueInterp=%{public}f, "\
54         " mPosBrightness=%{public}f", lux, valueInterp, mPosBrightness);
55     return valueInterp;
56 }
57 
GetInterpolatedBrightenssLevel(float positionBrightness,float lux)58 float BrightnessCalculationManager::GetInterpolatedBrightenssLevel(float positionBrightness, float lux)
59 {
60     float posBrightness = positionBrightness;
61     UpdateCurveAmbientLux(lux);
62     UpdateDefaultBrightness(lux);
63 
64     if (mLastLuxDefaultBrightness <= DEFAULT_OFFSET_BRIGHTNESS && mPosBrightness != DEFAULT_OFFSET_BRIGHTNESS) {
65         posBrightness = DEFAULT_OFFSET_BRIGHTNESS;
66         ResetDefaultBrightnessOffset();
67     }
68 
69     float offsetBrightness = mDefaultBrightnessFromLux;
70     if (IsDefaultBrightnessMode(posBrightness)) {
71         offsetBrightness = mDefaultBrightnessFromLux;
72     } else {
73         offsetBrightness = GetOffsetLevel(mStartLuxDefaultBrightness,
74             mDefaultBrightnessFromLux, posBrightness, mDelta);
75     }
76 
77     mLastLuxDefaultBrightness = mDefaultBrightnessFromLux;
78     mOffsetBrightnessLast = offsetBrightness;
79     DISPLAY_HILOGI(FEAT_BRIGHTNESS, "GetLevel lux=%{public}f, offsetBrightness=%{public}f, default=%{public}f",
80         lux, offsetBrightness, mDefaultBrightnessFromLux);
81     return offsetBrightness;
82 }
83 
UpdateDefaultBrightness(float lux)84 void BrightnessCalculationManager::UpdateDefaultBrightness(float lux)
85 {
86     float defaultBrightness = GetCurrentBrightness(lux);
87     mDefaultBrightnessFromLux = defaultBrightness;
88 }
89 
GetCurrentBrightness(float lux)90 float BrightnessCalculationManager::GetCurrentBrightness(float lux)
91 {
92     return mBrightnessCalculationCurve.GetCurrentBrightness(lux);
93 }
94 
UpdateParaFromReboot()95 void BrightnessCalculationManager::UpdateParaFromReboot()
96 {
97     mLastLuxDefaultBrightness = mDefaultBrightnessFromLux;
98     mStartLuxDefaultBrightness = mDefaultBrightnessFromLux;
99     mOffsetBrightnessLast = mDefaultBrightnessFromLux;
100     mIsReboot = false;
101 }
102 
IsDefaultBrightnessMode(float positionBrightness)103 bool BrightnessCalculationManager::IsDefaultBrightnessMode(float positionBrightness)
104 {
105     if (positionBrightness == DEFAULT_OFFSET_DELTA) {
106         return true;
107     }
108     return false;
109 }
110 
GetOffsetLevel(float brightnessStartOrig,float brightnessEndOrig,float brightnessStartNew,float delta)111 float BrightnessCalculationManager::GetOffsetLevel(float brightnessStartOrig, float brightnessEndOrig,
112     float brightnessStartNew, float delta)
113 {
114     float brightenRatio = 1.0f;
115     float darkenRatio = 1.0f;
116     float deltaStart = delta;
117     if (brightnessStartOrig < brightnessEndOrig) {
118         if (deltaStart > DEFAULT_OFFSET_DELTA) {
119             darkenRatio = GetDefaultBrightenOffsetBrightenRaio(brightnessStartOrig, brightnessEndOrig,
120                 brightnessStartNew, deltaStart);
121         }
122         if (deltaStart < DEFAULT_OFFSET_DELTA) {
123             brightenRatio = GetDefaultDarkenOffsetBrightenRatio(brightnessStartOrig, brightnessEndOrig,
124                 brightnessStartNew, deltaStart);
125         }
126     }
127     if (brightnessStartOrig > brightnessEndOrig) {
128         if (deltaStart < DEFAULT_OFFSET_DELTA) {
129             darkenRatio = GetDefaultDarkenOffsetDarkenRatio(brightnessStartOrig, brightnessEndOrig,
130                 brightnessStartNew, deltaStart);
131         }
132         if (deltaStart > DEFAULT_OFFSET_DELTA) {
133             brightenRatio = GetDefaultBrightenOffsetDarkenRatio(brightnessStartOrig, brightnessEndOrig,
134                 brightnessStartNew);
135         }
136     }
137     float tempDeltaNew = deltaStart * brightenRatio * darkenRatio;
138 
139     float brightnessAndDelta = brightnessEndOrig + tempDeltaNew;
140     float offsetBrightnessTemp = (brightnessAndDelta > MIN_DEFAULT_BRIGHTNESS
141         ? brightnessAndDelta : MIN_DEFAULT_BRIGHTNESS);
142     float offsetBrightness = (offsetBrightnessTemp < MAX_DEFAULT_BRIGHTNESS
143         ? offsetBrightnessTemp : MAX_DEFAULT_BRIGHTNESS);
144     DISPLAY_HILOGI(FEAT_BRIGHTNESS, "GetOffsetLevel tempDeltaNew=%{public}f, deltaStart=%{public}f, "\
145         " brightenRatio=%{public}f, darkenRatio=%{public}f", tempDeltaNew, deltaStart, brightenRatio, darkenRatio);
146     return offsetBrightness;
147 }
148 
GetDefaultBrightenOffsetBrightenRaio(float brightnessStartOrig,float brightnessEndOrig,float brightnessStartNew,float deltaStart)149 float BrightnessCalculationManager::GetDefaultBrightenOffsetBrightenRaio(float brightnessStartOrig,
150     float brightnessEndOrig, float brightnessStartNew, float deltaStart)
151 {
152     float brightenRatio;
153     if (std::abs(MAX_DEFAULT_BRIGHTNESS - brightnessStartOrig) < SMALL_VALUE) {
154         brightenRatio = DEFAULT_OFFSET_RATIO;
155     } else {
156         brightenRatio = (MAX_DEFAULT_BRIGHTNESS - brightnessEndOrig)
157             / (MAX_DEFAULT_BRIGHTNESS - brightnessStartOrig);
158     }
159 
160     float offsetBrightnessTmp = ((1 - offsetBrightenAlphaRight)
161         * std::max(brightnessEndOrig, brightnessStartNew))
162         + (offsetBrightenAlphaRight * ((deltaStart * brightenRatio) + brightnessEndOrig));
163     if (std::abs(deltaStart) < SMALL_VALUE) {
164         brightenRatio = DEFAULT_OFFSET_RATIO;
165     } else {
166         brightenRatio = (offsetBrightnessTmp - brightnessEndOrig) / deltaStart;
167     }
168     if (brightenRatio < MIN_OFFSET_RATIO) {
169         brightenRatio = MIN_OFFSET_RATIO;
170     }
171     return brightenRatio;
172 }
173 
174 
GetAmbientOffsetLux()175 float BrightnessCalculationManager::GetAmbientOffsetLux()
176 {
177     float lux = static_cast<int>(mOffsetLux);
178     return lux;
179 }
180 
GetBrightenOffsetNoValidBrightenLux(float lux)181 float BrightnessCalculationManager::GetBrightenOffsetNoValidBrightenLux(float lux)
182 {
183     float noValidBrightenLuxTh = AMBIENT_VALID_MAX_LUX;
184     return noValidBrightenLuxTh;
185 }
186 
GetDefaultDarkenOffsetBrightenRatio(float brightnessStartOrig,float brightnessEndOrig,float brightnessStartNew,float deltaStart)187 float BrightnessCalculationManager::GetDefaultDarkenOffsetBrightenRatio(float brightnessStartOrig,
188     float brightnessEndOrig, float brightnessStartNew, float deltaStart)
189 {
190     float brightenRatio;
191     if (std::abs(MAX_DEFAULT_BRIGHTNESS - brightnessStartOrig) < SMALL_VALUE) {
192         brightenRatio = DEFAULT_OFFSET_RATIO;
193     } else {
194         brightenRatio = (MAX_DEFAULT_BRIGHTNESS - brightnessEndOrig)
195             / (MAX_DEFAULT_BRIGHTNESS - brightnessStartOrig);
196     }
197 
198     if (brightenRatio < MIN_OFFSET_RATIO) {
199         brightenRatio = MIN_OFFSET_RATIO;
200     }
201     return brightenRatio;
202 }
203 
GetDefaultDarkenOffsetDarkenRatio(float brightnessStartOrig,float brightnessEndOrig,float brightnessStartNew,float deltaStart)204 float BrightnessCalculationManager::GetDefaultDarkenOffsetDarkenRatio(float brightnessStartOrig,
205     float brightnessEndOrig, float brightnessStartNew, float deltaStart)
206 {
207     float darkenRatio;
208     if (std::abs(brightnessStartOrig - MIN_DEFAULT_BRIGHTNESS) < SMALL_VALUE) {
209         darkenRatio = DEFAULT_OFFSET_RATIO;
210     } else {
211         darkenRatio = (brightnessEndOrig - MIN_DEFAULT_BRIGHTNESS)
212             / (brightnessStartOrig - MIN_DEFAULT_BRIGHTNESS);
213     }
214     float offsetBrightnessTmp = ((1 - offsetDarkenAlphaLeft) * std::min(brightnessEndOrig,
215         brightnessStartNew)) + (offsetDarkenAlphaLeft * ((deltaStart * darkenRatio) + brightnessEndOrig));
216     if (std::abs(deltaStart) < SMALL_VALUE) {
217         darkenRatio = DEFAULT_OFFSET_RATIO;
218     } else {
219         darkenRatio = (offsetBrightnessTmp - brightnessEndOrig) / deltaStart;
220     }
221     if (darkenRatio < MIN_OFFSET_RATIO) {
222         darkenRatio = MIN_OFFSET_RATIO;
223     }
224     return darkenRatio;
225 }
226 
GetDefaultBrightenOffsetDarkenRatio(float brightnessStartOrig,float brightnessEndOrig,float brightnessStartNew)227 float BrightnessCalculationManager::GetDefaultBrightenOffsetDarkenRatio(float brightnessStartOrig,
228     float brightnessEndOrig, float brightnessStartNew)
229 {
230     float darkenRatio;
231     if (std::abs(brightnessStartOrig) < SMALL_VALUE) {
232         darkenRatio = DEFAULT_OFFSET_RATIO;
233     } else {
234         float darkenRatioTmp = static_cast<float>(pow(brightnessEndOrig / brightnessStartOrig,
235             offsetBrightenRatioLeft));
236         darkenRatio = (offsetBrightenAlphaLeft * brightnessEndOrig / brightnessStartOrig)
237             + ((1 - offsetBrightenAlphaLeft) * darkenRatioTmp);
238     }
239     return darkenRatio;
240 }
241 
UpdateBrightnessOffset(float posBrightness,float lux)242 void BrightnessCalculationManager::UpdateBrightnessOffset(float posBrightness, float lux)
243 {
244     if (lux < AMBIENT_VALID_MIN_LUX || lux > AMBIENT_VALID_MAX_LUX) {
245         return;
246     }
247     if (std::abs(posBrightness) < SMALL_VALUE) {
248         ResetDefaultBrightnessOffset();
249         return;
250     }
251     mOffsetLux = lux;
252     mStartLuxDefaultBrightness = GetCurrentBrightness(lux);
253     mPosBrightness = posBrightness;
254     mDelta = mPosBrightness - mStartLuxDefaultBrightness;
255     DISPLAY_HILOGI(FEAT_BRIGHTNESS, "UpdateBrightnessOffset lux=%{public}f, mDelta=%{public}f, "\
256      "mPosBrightness=%{public}f", lux, mDelta, mPosBrightness);
257 }
258 
ResetDefaultBrightnessOffset()259 void BrightnessCalculationManager::ResetDefaultBrightnessOffset()
260 {
261     mOffsetLux = DEFAULT_NO_OFFSET_LUX;
262     mDelta = DEFAULT_OFFSET_DELTA;
263 
264     mOffsetBrightnessLast = DEFAULT_OFFSET_BRIGHTNESS;
265     mLastLuxDefaultBrightness = DEFAULT_OFFSET_BRIGHTNESS;
266     mStartLuxDefaultBrightness = DEFAULT_OFFSET_BRIGHTNESS;
267     mPosBrightness = DEFAULT_OFFSET_BRIGHTNESS;
268     DISPLAY_HILOGI(FEAT_BRIGHTNESS, "ResetDefaultBrightnessOffset");
269 }
270 
UpdateCurveAmbientLux(float lux)271 void BrightnessCalculationManager::UpdateCurveAmbientLux(float lux)
272 {
273     if (mCurveLux != lux) {
274         mBrightnessCalculationCurve.UpdateCurveAmbientLux(lux);
275         mCurveLux = lux;
276     }
277 }
278 
SetGameModeEnable(bool isGameCurveEnable)279 void BrightnessCalculationManager::SetGameModeEnable(bool isGameCurveEnable)
280 {
281     mIsGameCurveEnable = isGameCurveEnable;
282 }
283 
SetCameraModeEnable(bool isCameraCurveEnable)284 void BrightnessCalculationManager::SetCameraModeEnable(bool isCameraCurveEnable)
285 {
286     mIsCameraCurveEnable = isCameraCurveEnable;
287 }
288 
UpdateCurrentUserId(int userId)289 void BrightnessCalculationManager::UpdateCurrentUserId(int userId)
290 {
291     mCurrentUserId = userId;
292     mBrightnessCalculationCurve.UpdateCurrentUserId(userId);
293 }
294 
ResetOffsetFromHumanFactor(bool isOffsetResetEnable,int minOffsetBrightness,int maxOffsetBrightness)295 void BrightnessCalculationManager::ResetOffsetFromHumanFactor(bool isOffsetResetEnable, int minOffsetBrightness,
296     int maxOffsetBrightness)
297 {
298     if (isOffsetResetEnable && std::abs(mPosBrightness) > SMALL_VALUE) {
299         if (mPosBrightness < minOffsetBrightness) {
300             mPosBrightness = minOffsetBrightness;
301             mOffsetBrightnessLast = minOffsetBrightness;
302             mDelta = mPosBrightness - mStartLuxDefaultBrightness;
303         }
304         if (mPosBrightness > maxOffsetBrightness) {
305             mPosBrightness = maxOffsetBrightness;
306             mOffsetBrightnessLast = maxOffsetBrightness;
307             mDelta = mPosBrightness - mStartLuxDefaultBrightness;
308         }
309     }
310 }
311 
GetDisplayIdWithDisplayMode(int displayMode)312 int BrightnessCalculationManager::GetDisplayIdWithDisplayMode(int displayMode)
313 {
314     return mBrightnessCalculationCurve.GetDisplayIdWithDisplayMode(displayMode);
315 }
316 
GetSensorIdWithDisplayMode(int displayMode)317 int BrightnessCalculationManager::GetSensorIdWithDisplayMode(int displayMode)
318 {
319     return mBrightnessCalculationCurve.GetSensorIdWithDisplayMode(displayMode);
320 }
321 
GetDisplayIdWithFoldstatus(int foldStatus)322 int BrightnessCalculationManager::GetDisplayIdWithFoldstatus(int foldStatus)
323 {
324     return mBrightnessCalculationCurve.GetDisplayIdWithFoldstatus(foldStatus);
325 }
326 
GetSensorIdWithFoldstatus(int foldStatus)327 int BrightnessCalculationManager::GetSensorIdWithFoldstatus(int foldStatus)
328 {
329     return mBrightnessCalculationCurve.GetSensorIdWithFoldstatus(foldStatus);
330 }
331 } // namespace DisplayPowerMgr
332 } // namespace OHOS