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