• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "screen_brightness_task.h"
17 
18 #include <string>
19 #include <vector>
20 
21 #include "display_power_mgr_client.h"
22 #include "parameter.h"
23 #include "sensor_agent.h"
24 
25 #include "iam_check.h"
26 #include "iam_logger.h"
27 #include "iam_ptr.h"
28 
29 #include "finite_state_machine.h"
30 #include "screen_brightness_manager.h"
31 
32 #define LOG_LABEL UserIam::Common::LABEL_FACE_AUTH_SA
33 
34 namespace OHOS {
35 namespace UserIam {
36 namespace FaceAuth {
37 using ResultCode = UserAuth::ResultCode;
38 using namespace DisplayPowerMgr;
39 namespace {
40 constexpr SensorUser SENSOR_USER = {
41     "FaceAuthService",
__anond7b5d8080202() 42     [](SensorEvent *event) {
43         IF_FALSE_LOGE_AND_RETURN(event != nullptr);
44         IF_FALSE_LOGE_AND_RETURN(event->sensorTypeId == SENSOR_TYPE_ID_AMBIENT_LIGHT);
45         auto data = static_cast<AmbientLightData *>(static_cast<void *>(event->data));
46         IF_FALSE_LOGE_AND_RETURN(data != nullptr);
47 
48         auto manager = ScreenBrightnessManager::GetInstance();
49         IF_FALSE_LOGE_AND_RETURN(manager != nullptr);
50         auto task = manager->GetCurrentTask();
51         IF_FALSE_LOGE_AND_RETURN(task != nullptr);
52 
53         task->SetAmbientLight(data->intensity);
54     },
55 };
56 constexpr uint32_t INVALID_BRIGHTNESS = -1;
57 constexpr uint32_t SENSOR_SAMPLE_AND_REPORT_INTERVAL = 100 * 1000 * 1000; // ns
58 constexpr uint32_t INCREASE_BRIGHTNESS_START_DELAY = 100;                 // ms
59 constexpr uint32_t DEFAULT_INCREASE_BRIGHTNESS_INTERVAL = 75;             // ms
60 constexpr uint32_t DEFAULT_INCREASE_BRIGHTNESS_MAX = 30;
61 const std::vector<uint32_t> INCREASE_BRIGHTNESS_ARRAY = { 4, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, 11, 13, 14, 15, 17, 18, 20,
62     22, 24, 27, 30, 33, 36, 39, 43, 48, 52, 58, 63, 70, 77, 84, 93, 102, 112, 124, 136, 150, 166, 181, 199, 219, 241 };
63 constexpr float AMBIENT_LIGHT_THRESHOLD_FOR_BEGIN = 2.0; // lux
64 constexpr uint32_t MAX_BRIGHTNESS = 255;
65 constexpr uint32_t MAX_INT_STRING_LEN = 12;
66 constexpr float INVALID_AMBIENT_LIGHT_LUX = -1.0;
67 const char *INCREASE_BRIGHTNESS_MAX_KEY = "const.useriam.face_auth_increase_brightness_max";
68 const char *INCREASE_BRIGHTNESS_INTERVAL_KEY = "const.useriam.face_auth_increase_brightness_interval";
69 
GetUInt32Param(const char * key,uint32_t defaultValue)70 uint32_t GetUInt32Param(const char *key, uint32_t defaultValue)
71 {
72     std::string defaultStr = std::to_string(defaultValue);
73     char str[MAX_INT_STRING_LEN] = { 0 };
74     int32_t ret = GetParameter(key, defaultStr.c_str(), str, MAX_INT_STRING_LEN - 1);
75     if (ret < 0) {
76         IAM_LOGE("failed to get param %{public}s, return default value", key);
77         return defaultValue;
78     }
79     uint32_t uintValue;
80     try {
81         unsigned long longValue = std::stoul(str);
82         if (longValue > std::numeric_limits<uint32_t>::max()) {
83             IAM_LOGE("value exceeds uint32");
84             return std::numeric_limits<uint32_t>::max();
85         }
86         uintValue = static_cast<uint32_t>(longValue);
87     } catch (const std::exception &e) {
88         IAM_LOGE("failed to convert %{public}s to int, return default value", str);
89         return defaultValue;
90     }
91 
92     return uintValue;
93 }
94 
GetIncreaseBrightnessInterval()95 uint32_t GetIncreaseBrightnessInterval()
96 {
97     uint32_t val = GetUInt32Param(INCREASE_BRIGHTNESS_INTERVAL_KEY, DEFAULT_INCREASE_BRIGHTNESS_INTERVAL);
98     if (val == 0) {
99         IAM_LOGE("interval cannot be 0");
100         return DEFAULT_INCREASE_BRIGHTNESS_INTERVAL;
101     }
102     IAM_LOGI("param interval %{public}u", val);
103     return val;
104 }
105 
GetIncreaseBrightnessMax()106 uint32_t GetIncreaseBrightnessMax()
107 {
108     uint32_t val = GetUInt32Param(INCREASE_BRIGHTNESS_MAX_KEY, DEFAULT_INCREASE_BRIGHTNESS_MAX);
109     if (val > MAX_BRIGHTNESS) {
110         IAM_LOGE("val exceeds max brightness");
111         return MAX_BRIGHTNESS;
112     }
113     IAM_LOGI("param increase brightness max %{public}u", val);
114     return val;
115 }
116 
SubscribeSensor()117 ResultCode SubscribeSensor()
118 {
119     IAM_LOGI("start");
120     int32_t subscribeSensorRet = SubscribeSensor(SENSOR_TYPE_ID_AMBIENT_LIGHT, &SENSOR_USER);
121     IF_FALSE_LOGE_AND_RETURN_VAL(subscribeSensorRet == 0, ResultCode::GENERAL_ERROR);
122     int32_t setBatchRet = SetBatch(SENSOR_TYPE_ID_AMBIENT_LIGHT, &SENSOR_USER, SENSOR_SAMPLE_AND_REPORT_INTERVAL,
123         SENSOR_SAMPLE_AND_REPORT_INTERVAL);
124     IF_FALSE_LOGE_AND_RETURN_VAL(setBatchRet == 0, ResultCode::GENERAL_ERROR);
125     int32_t activateSensorRet = ActivateSensor(SENSOR_TYPE_ID_AMBIENT_LIGHT, &SENSOR_USER);
126     IF_FALSE_LOGE_AND_RETURN_VAL(activateSensorRet == 0, ResultCode::GENERAL_ERROR);
127     int32_t setModeRet = SetMode(SENSOR_TYPE_ID_AMBIENT_LIGHT, &SENSOR_USER, SENSOR_ON_CHANGE);
128     IF_FALSE_LOGE_AND_RETURN_VAL(setModeRet == 0, ResultCode::GENERAL_ERROR);
129 
130     return ResultCode::SUCCESS;
131 }
132 
UnsubscribeSensor()133 void UnsubscribeSensor()
134 {
135     IAM_LOGI("start");
136     DeactivateSensor(SENSOR_TYPE_ID_AMBIENT_LIGHT, &SENSOR_USER);
137     UnsubscribeSensor(SENSOR_TYPE_ID_AMBIENT_LIGHT, &SENSOR_USER);
138     return;
139 }
140 
GetIncreaseBrightnessStartIndex(uint32_t currentBrightness)141 uint32_t GetIncreaseBrightnessStartIndex(uint32_t currentBrightness)
142 {
143     for (uint32_t i = 0; i < INCREASE_BRIGHTNESS_ARRAY.size(); i++) {
144         if (INCREASE_BRIGHTNESS_ARRAY[i] > currentBrightness) {
145             return i;
146         }
147     }
148     return INCREASE_BRIGHTNESS_ARRAY.size();
149 }
150 
OverrideScreenBrightness(uint32_t brightness)151 void OverrideScreenBrightness(uint32_t brightness)
152 {
153     int32_t displayId = DisplayPowerMgrClient::GetInstance().GetMainDisplayId();
154     if (!DisplayPowerMgrClient::GetInstance().OverrideBrightness(brightness, displayId)) {
155         IAM_LOGE("override brightness fail");
156         return;
157     }
158 }
159 
RestoreScreenBrightness()160 void RestoreScreenBrightness()
161 {
162     int32_t displayId = DisplayPowerMgrClient::GetInstance().GetMainDisplayId();
163     if (!DisplayPowerMgrClient::GetInstance().RestoreBrightness(displayId)) {
164         IAM_LOGE("restore brightness fail");
165         return;
166     }
167 }
168 
GetCurrentScreenBrightness()169 uint32_t GetCurrentScreenBrightness()
170 {
171     return DisplayPowerMgrClient::GetInstance().GetDeviceBrightness();
172 }
173 
ShouldBeginIncreaseBrightness(float currentAmbientLightLux)174 bool ShouldBeginIncreaseBrightness(float currentAmbientLightLux)
175 {
176     return currentAmbientLightLux < AMBIENT_LIGHT_THRESHOLD_FOR_BEGIN;
177 }
178 } // namespace
179 
ScreenBrightnessTask()180 ScreenBrightnessTask::ScreenBrightnessTask() : timer_("screen_brightness_timer")
181 {
182     timer_.Setup();
183     increaseBrightnessIndex_ = 0;
184     increaseBrightnessInterval_ = GetIncreaseBrightnessInterval();
185     increaseBrightnessMax_ = GetIncreaseBrightnessMax();
186     currTimerId_ = 0;
187     currentBrightness_ = 0;
188     currentAmbientLightLux_ = INVALID_AMBIENT_LIGHT_LUX;
189 }
190 
~ScreenBrightnessTask()191 ScreenBrightnessTask::~ScreenBrightnessTask()
192 {
193     timer_.Unregister(currTimerId_);
194     timer_.Shutdown();
195     if (machine_ != nullptr) {
196         // make sure state machine is stopped
197         uint32_t state = machine_->EnsureCurrentState();
198         if (state != S_END) {
199             IAM_LOGE("state is not STOP when destruct");
200         }
201     }
202     if (destructCallback_ != nullptr) {
203         destructCallback_();
204     }
205 }
206 
Start()207 void ScreenBrightnessTask::Start()
208 {
209     machine_ = MakeFiniteStateMachine();
210     IF_FALSE_LOGE_AND_RETURN(machine_ != nullptr);
211 
212     machine_->Schedule(E_START);
213 }
214 
Stop()215 void ScreenBrightnessTask::Stop()
216 {
217     IF_FALSE_LOGE_AND_RETURN(machine_ != nullptr);
218     machine_->Schedule(E_STOP);
219 }
220 
MakeFiniteStateMachine()221 std::shared_ptr<FiniteStateMachine> ScreenBrightnessTask::MakeFiniteStateMachine()
222 {
223     auto builder = FiniteStateMachine::Builder::New("ScreenBrightnessTask", State::S_INIT);
224     IF_FALSE_LOGE_AND_RETURN_VAL(builder != nullptr, nullptr);
225 
226     // S_INIT
227     builder->MakeTransition(S_INIT, E_START, S_WAIT_AMBIENT_LIGHT_INFO_AND_START_DELAY,
228         [self = this](FiniteStateMachine &machine, uint32_t event) { self->StartProcess(); });
229 
230     // S_WAIT_*
231     builder->MakeTransition(S_WAIT_AMBIENT_LIGHT_INFO_AND_START_DELAY, E_START_DELAY_EXPIRED,
232         S_WAIT_AMBIENT_LIGHT_INFO);
233     builder->MakeTransition(S_WAIT_AMBIENT_LIGHT_INFO_AND_START_DELAY, E_RECEIVE_AMBIENT_LIGHT_INFO,
234         S_WAIT_START_DELAY);
235     builder->MakeTransition(S_WAIT_AMBIENT_LIGHT_INFO, E_RECEIVE_AMBIENT_LIGHT_INFO, S_INCREASING_BRIGHTNESS);
236     builder->MakeTransition(S_WAIT_START_DELAY, E_START_DELAY_EXPIRED, S_INCREASING_BRIGHTNESS);
237 
238     // S_INCREASING_BRIGHTNESS
239     builder->MakeOnStateEnter(S_INCREASING_BRIGHTNESS,
240         [self = this](FiniteStateMachine &machine, uint32_t event) { self->BeginIncreaseBrightness(); });
241 
242     builder->MakeTransition(S_INCREASING_BRIGHTNESS, E_INCREASE_BRIGHTNESS, S_INCREASING_BRIGHTNESS,
243         [self = this](FiniteStateMachine &machine, uint32_t event) { self->DoIncreaseBrightness(); });
244 
245     // S_END
246     builder->MakeOnStateEnter(S_END,
247         [self = this](FiniteStateMachine &machine, uint32_t event) { self->EndProcess(); });
248 
249     // process E_STOP
250     builder->MakeTransition(S_WAIT_AMBIENT_LIGHT_INFO_AND_START_DELAY, E_STOP, S_END);
251     builder->MakeTransition(S_WAIT_AMBIENT_LIGHT_INFO, E_STOP, S_END);
252     builder->MakeTransition(S_WAIT_START_DELAY, E_STOP, S_END);
253     builder->MakeTransition(S_INCREASING_BRIGHTNESS, E_STOP, S_END);
254     builder->MakeTransition(S_END, E_STOP, S_END);
255 
256     // ignore E_RECEIVE_AMBIENT_LIGHT_INFO
257     builder->MakeTransition(S_WAIT_START_DELAY, E_RECEIVE_AMBIENT_LIGHT_INFO, S_WAIT_START_DELAY);
258     builder->MakeTransition(S_INCREASING_BRIGHTNESS, E_RECEIVE_AMBIENT_LIGHT_INFO, S_INCREASING_BRIGHTNESS);
259     builder->MakeTransition(S_END, E_RECEIVE_AMBIENT_LIGHT_INFO, S_END);
260     return builder->Build();
261 }
262 
SetAmbientLight(float lux)263 void ScreenBrightnessTask::SetAmbientLight(float lux)
264 {
265     IAM_LOGI("receive ambient light %{public}f", lux);
266     {
267         std::lock_guard<std::mutex> lock(currentAmbientLightLuxMutex_);
268         currentAmbientLightLux_ = lux;
269     }
270 
271     IF_FALSE_LOGE_AND_RETURN(machine_ != nullptr);
272     machine_->Schedule(E_RECEIVE_AMBIENT_LIGHT_INFO);
273 }
274 
OnStartDelayTimeout()275 void ScreenBrightnessTask::OnStartDelayTimeout()
276 {
277     IAM_LOGI("start");
278     IF_FALSE_LOGE_AND_RETURN(machine_ != nullptr);
279     machine_->Schedule(E_START_DELAY_EXPIRED);
280 }
281 
OnIncreaseBrightness()282 void ScreenBrightnessTask::OnIncreaseBrightness()
283 {
284     IAM_LOGI("start");
285     IF_FALSE_LOGE_AND_RETURN(machine_ != nullptr);
286     machine_->Schedule(E_INCREASE_BRIGHTNESS);
287 }
288 
StartProcess()289 void ScreenBrightnessTask::StartProcess()
290 {
291     IAM_LOGI("start");
292     IF_FALSE_LOGE_AND_RETURN(machine_ != nullptr);
293 
294     ResultCode result = SubscribeSensor();
295     if (result != ResultCode::SUCCESS) {
296         IAM_LOGE("SubscribeSensor fail");
297         machine_->Schedule(E_STOP);
298         return;
299     }
300 
301     timer_.Unregister(currTimerId_);
302     currTimerId_ = timer_.Register(
303         [weak_self = weak_from_this()]() {
304             auto self = weak_self.lock();
305             if (self == nullptr) {
306                 IAM_LOGE("object is released");
307                 return;
308             }
309             self->OnStartDelayTimeout();
310         },
311         INCREASE_BRIGHTNESS_START_DELAY, true);
312 
313     IAM_LOGI("time id %{public}d", currTimerId_);
314 }
315 
BeginIncreaseBrightness()316 void ScreenBrightnessTask::BeginIncreaseBrightness()
317 {
318     IAM_LOGI("start");
319     IF_FALSE_LOGE_AND_RETURN(machine_ != nullptr);
320 
321     bool shouldIncrease = false;
322     {
323         std::lock_guard<std::mutex> lock(currentAmbientLightLuxMutex_);
324         shouldIncrease = ShouldBeginIncreaseBrightness(currentAmbientLightLux_);
325     }
326     if (!shouldIncrease) {
327         IAM_LOGI("no need increase");
328         machine_->Schedule(E_STOP);
329         return;
330     }
331 
332     currentBrightness_ = GetCurrentScreenBrightness();
333     IF_FALSE_LOGE_AND_RETURN(currentBrightness_ != INVALID_BRIGHTNESS);
334     increaseBrightnessIndex_ = GetIncreaseBrightnessStartIndex(currentBrightness_);
335     IF_FALSE_LOGE_AND_RETURN(increaseBrightnessIndex_ < INCREASE_BRIGHTNESS_ARRAY.size());
336 
337     IAM_LOGI("current brightness %{public}u array index %{public}u value %{public}u", currentBrightness_,
338         increaseBrightnessIndex_, INCREASE_BRIGHTNESS_ARRAY[increaseBrightnessIndex_]);
339     DoIncreaseBrightness();
340 }
341 
DoIncreaseBrightness()342 void ScreenBrightnessTask::DoIncreaseBrightness()
343 {
344     IAM_LOGI("start");
345 
346     auto timeCallback = [weak_self = weak_from_this()]() {
347         auto self = weak_self.lock();
348         if (self == nullptr) {
349             IAM_LOGE("object is released");
350             return;
351         }
352         self->OnIncreaseBrightness();
353     };
354 
355     if (increaseBrightnessIndex_ < INCREASE_BRIGHTNESS_ARRAY.size()) {
356         if (INCREASE_BRIGHTNESS_ARRAY[increaseBrightnessIndex_] <= increaseBrightnessMax_) {
357             OverrideScreenBrightness(INCREASE_BRIGHTNESS_ARRAY[increaseBrightnessIndex_]);
358             IAM_LOGI("increase brightness index %{public}u value %{public}u", increaseBrightnessIndex_,
359                 INCREASE_BRIGHTNESS_ARRAY[increaseBrightnessIndex_]);
360             timer_.Unregister(currTimerId_);
361             currTimerId_ = timer_.Register(timeCallback, increaseBrightnessInterval_, true);
362         }
363         increaseBrightnessIndex_++;
364     }
365 }
366 
EndProcess()367 void ScreenBrightnessTask::EndProcess()
368 {
369     IAM_LOGI("start");
370     timer_.Unregister(currTimerId_);
371     UnsubscribeSensor();
372     RestoreScreenBrightness();
373 }
374 
RegisterDestructCallback(DestructCallback destructCallback)375 void ScreenBrightnessTask::RegisterDestructCallback(DestructCallback destructCallback)
376 {
377     destructCallback_ = destructCallback;
378 }
379 
GetScreenBrightnessTask()380 __attribute__((visibility("default"))) std::shared_ptr<IScreenBrightnessTask> GetScreenBrightnessTask()
381 {
382     return Common::MakeShared<ScreenBrightnessTask>();
383 }
384 } // namespace FaceAuth
385 } // namespace UserIam
386 } // namespace OHOS