1 /*
2 * Copyright (c) 2021-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_controller.h"
17
18 #include "delayed_sp_singleton.h"
19 #include "display_common.h"
20 #include "display_log.h"
21 #include "display_param_helper.h"
22 #include "display_power_mgr_service.h"
23 #include "display_setting_helper.h"
24 #include "ffrt_utils.h"
25 #include "refbase.h"
26 #include "setting_provider.h"
27 #include "system_ability_definition.h"
28 #include "power_state_machine_info.h"
29
30 using namespace std;
31 using namespace OHOS::PowerMgr;
32
33 namespace OHOS {
34 namespace DisplayPowerMgr {
35 namespace {
36 FFRTQueue g_queue("screen_controller");
37 FFRTHandle g_cancelBoostTaskHandle;
38 }
39
ScreenController(uint32_t displayId)40 ScreenController::ScreenController(uint32_t displayId)
41 {
42 DISPLAY_HILOGI(COMP_SVC, "ScreenController created for displayId=%{public}u", displayId);
43 action_ = make_shared<ScreenAction>(displayId);
44 state_ = action_->GetDisplayState();
45
46 string name = "BrightnessController_" + to_string(displayId);
47 if (animateCallback_ == nullptr) {
48 animateCallback_ = make_shared<AnimateCallbackImpl>([this](uint32_t brightness) {
49 SetSettingBrightness(brightness);
50 });
51 }
52 animator_ = make_shared<GradualAnimator>(name, animateCallback_);
53 }
54
AnimateCallbackImpl(std::function<void (uint32_t)> callback)55 ScreenController::AnimateCallbackImpl::AnimateCallbackImpl(std::function<void(uint32_t)> callback) : callback_(callback)
56 {
57 }
58
OnStart()59 void ScreenController::AnimateCallbackImpl::OnStart()
60 {
61 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "ScreenAnimatorCallback onStart");
62 }
63
OnChanged(uint32_t currentValue)64 void ScreenController::AnimateCallbackImpl::OnChanged(uint32_t currentValue)
65 {
66 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "OnChanged, no Update brightness");
67 }
68
OnEnd()69 void ScreenController::AnimateCallbackImpl::OnEnd()
70 {
71 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "ScreenAnimatorCallback OnEnd");
72 }
73
DiscountBrightness(double discount)74 void ScreenController::AnimateCallbackImpl::DiscountBrightness(double discount)
75 {
76 discount_ = discount;
77 }
78
GetState()79 DisplayState ScreenController::GetState()
80 {
81 return state_;
82 }
83
SetDelayOffState()84 DisplayState ScreenController::SetDelayOffState()
85 {
86 DISPLAY_HILOGI(COMP_SVC, "Set the display state is DELAY OFF when overriding display off delay");
87 state_ = DisplayState::DISPLAY_DELAY_OFF;
88 return state_;
89 }
90
SetOnState()91 DisplayState ScreenController::SetOnState()
92 {
93 DISPLAY_HILOGI(COMP_SVC, "Set the display state is ON after overriding display on delay");
94 state_ = DisplayState::DISPLAY_ON;
95 return state_;
96 }
97
UpdateState(DisplayState state,uint32_t reason)98 bool ScreenController::UpdateState(DisplayState state, uint32_t reason)
99 {
100 DISPLAY_HILOGI(FEAT_STATE, "[UL_POWER] UpdateState, state=%{public}u, current state=%{public}u, reason=%{public}u",
101 static_cast<uint32_t>(state), static_cast<uint32_t>(state_), reason);
102 if (reason != static_cast<uint32_t>
103 (PowerMgr::StateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF)) {
104 RETURN_IF_WITH_RET(state == state_, true);
105 }
106 if (state == DisplayState::DISPLAY_DIM && state_ == DisplayState::DISPLAY_OFF) {
107 DISPLAY_HILOGI(FEAT_STATE, "Not allowed to set DIM state.");
108 return true;
109 }
110 switch (state) {
111 case DisplayState::DISPLAY_ON:
112 if (state_ == DisplayState::DISPLAY_DIM) {
113 break;
114 }
115 [[fallthrough]];
116 case DisplayState::DISPLAY_DOZE_SUSPEND:
117 case DisplayState::DISPLAY_DOZE:
118 case DisplayState::DISPLAY_OFF: {
119 if (action_->EnableSkipSetDisplayState(reason)) {
120 OnStateChanged(state, reason);
121 } else {
122 function<void(DisplayState)> callback =
123 bind(&ScreenController::OnStateChanged, this, placeholders::_1, reason);
124 bool ret = action_->SetDisplayState(state, callback);
125 if (!ret) {
126 DISPLAY_HILOGW(FEAT_STATE, "Update display state failed, state=%{public}d", state);
127 return ret;
128 }
129 }
130 break;
131 }
132 case DisplayState::DISPLAY_DIM:
133 case DisplayState::DISPLAY_SUSPEND:
134 default:
135 break;
136 }
137
138 if (IsNeedSkipNextProc(reason)) {
139 DISPLAY_HILOGI(FEAT_STATE,
140 "Need interrupt next process when updating state because of reason = %{public}d", reason);
141 return false;
142 }
143
144 lock_guard lock(mutexState_);
145 state_ = state;
146 stateChangeReason_ = reason;
147
148 DISPLAY_HILOGI(FEAT_STATE, "[UL_POWER] Update screen state to %{public}u", state);
149 return true;
150 }
151
IsScreenOn()152 bool ScreenController::IsScreenOn()
153 {
154 lock_guard lock(mutexState_);
155 return (state_ == DisplayState::DISPLAY_ON || state_ == DisplayState::DISPLAY_DIM);
156 }
157
SetBrightness(uint32_t value,uint32_t gradualDuration,bool continuous)158 bool ScreenController::SetBrightness(uint32_t value, uint32_t gradualDuration, bool continuous)
159 {
160 if (CanSetBrightness()) { // not set brightness
161 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot set brightness, ignore the change,"\
162 "cachedSettingBrightness_ %{public}u -> %{public}u", cachedSettingBrightness_.load(), value);
163 cachedSettingBrightness_ = value;
164 return false;
165 }
166 return UpdateBrightness(value, gradualDuration, !continuous);
167 }
168
GetBrightness()169 uint32_t ScreenController::GetBrightness()
170 {
171 return GetSettingBrightness();
172 }
173
GetDeviceBrightness()174 uint32_t ScreenController::GetDeviceBrightness()
175 {
176 return action_->GetBrightness();
177 }
178
GetCachedSettingBrightness() const179 uint32_t ScreenController::GetCachedSettingBrightness() const
180 {
181 return cachedSettingBrightness_;
182 }
183
DiscountBrightness(double discount,uint32_t gradualDuration)184 bool ScreenController::DiscountBrightness(double discount, uint32_t gradualDuration)
185 {
186 if (!CanDiscountBrightness()) {
187 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot discount brightness, ignore the change");
188 return false;
189 }
190 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Discount brightness, discount=%{public}f", discount);
191 discount_ = discount;
192 if (animateCallback_) {
193 animateCallback_->DiscountBrightness(discount);
194 }
195 uint32_t screenOnBrightness = GetScreenOnBrightness();
196 return UpdateBrightness(screenOnBrightness, gradualDuration);
197 }
198
OverrideBrightness(uint32_t value,uint32_t gradualDuration)199 bool ScreenController::OverrideBrightness(uint32_t value, uint32_t gradualDuration)
200 {
201 if (!CanOverrideBrightness()) {
202 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot override brightness, ignore the change");
203 return false;
204 }
205 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Override brightness, value=%{public}u", value);
206 if (!isBrightnessOverridden_) {
207 isBrightnessOverridden_ = true;
208 }
209 overriddenBrightness_ = value;
210 return UpdateBrightness(value, gradualDuration);
211 }
212
RestoreBrightness(uint32_t gradualDuration)213 bool ScreenController::RestoreBrightness(uint32_t gradualDuration)
214 {
215 if (!IsBrightnessOverridden()) {
216 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is not override, no need to restore");
217 return false;
218 }
219 isBrightnessOverridden_ = false;
220 return UpdateBrightness(cachedSettingBrightness_, gradualDuration, true);
221 }
222
IsBrightnessOverridden() const223 bool ScreenController::IsBrightnessOverridden() const
224 {
225 return isBrightnessOverridden_;
226 }
227
BoostBrightness(uint32_t timeoutMs,uint32_t gradualDuration)228 bool ScreenController::BoostBrightness(uint32_t timeoutMs, uint32_t gradualDuration)
229 {
230 if (!CanBoostBrightness()) {
231 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot boost brightness, ignore the change");
232 return false;
233 }
234 bool ret = true;
235 if (!isBrightnessBoosted_) {
236 uint32_t maxBrightness = DisplayParamHelper::GetMaxBrightness();
237 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Boost brightness, maxBrightness: %{public}d", maxBrightness);
238 isBrightnessBoosted_ = true;
239 ret = UpdateBrightness(maxBrightness, gradualDuration);
240 }
241
242 // If boost multi-times, we will resend the cancel boost event.
243 FFRTUtils::CancelTask(g_cancelBoostTaskHandle, g_queue);
244 FFRTTask task = [this, gradualDuration] { this->CancelBoostBrightness(gradualDuration); };
245 g_cancelBoostTaskHandle = FFRTUtils::SubmitDelayTask(task, timeoutMs, g_queue);
246 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "BoostBrightness update timeout=%{public}u, ret=%{public}d", timeoutMs, ret);
247 return ret;
248 }
249
CancelBoostBrightness(uint32_t gradualDuration)250 bool ScreenController::CancelBoostBrightness(uint32_t gradualDuration)
251 {
252 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Cancel boost brightness");
253 if (!IsBrightnessBoosted()) {
254 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is not boost, no need to restore");
255 return false;
256 }
257 FFRTUtils::CancelTask(g_cancelBoostTaskHandle, g_queue);
258 isBrightnessBoosted_ = false;
259 return UpdateBrightness(cachedSettingBrightness_, gradualDuration, true);
260 }
261
IsBrightnessBoosted() const262 bool ScreenController::IsBrightnessBoosted() const
263 {
264 return isBrightnessBoosted_;
265 }
266
IsNeedSkipNextProc(uint32_t reason)267 bool ScreenController::IsNeedSkipNextProc(uint32_t reason)
268 {
269 if (reason == static_cast<uint32_t>(PowerMgr::StateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT) ||
270 reason == static_cast<uint32_t>(
271 PowerMgr::StateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF)) {
272 return true;
273 }
274 return false;
275 }
276
OnStateChanged(DisplayState state,uint32_t reason)277 void ScreenController::OnStateChanged(DisplayState state, uint32_t reason)
278 {
279 auto pms = DelayedSpSingleton<DisplayPowerMgrService>::GetInstance();
280 if (pms == nullptr) {
281 DISPLAY_HILOGW(FEAT_STATE, "pms is nullptr");
282 return;
283 }
284 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "[UL_POWER] OnStateChanged state=%{public}d, reason=%{public}u",
285 static_cast<int>(state), reason);
286 bool ret = action_->SetDisplayPower(state, reason);
287 if (reason == static_cast<uint32_t>(PowerMgr::StateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT)) {
288 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "No need to set brightness, reason=%{public}d", reason);
289 return;
290 }
291 if (SkipNotify(state)) {
292 return;
293 }
294 if (state == DisplayState::DISPLAY_ON) {
295 bool result = false;
296 pms->SetScreenOnBrightness(result);
297 // Restore the brightness before screen off
298 uint32_t screenOnBrightness = GetScreenOnBrightness();
299 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "OnStateChanged set screenOnBrightness=%{public}d", screenOnBrightness);
300 }
301 if (state == DisplayState::DISPLAY_SUSPEND || state == DisplayState::DISPLAY_DOZE) {
302 state = DisplayState::DISPLAY_OFF;
303 }
304 if (ret) {
305 pms->NotifyStateChangeCallback(action_->GetDisplayId(), state, reason);
306 }
307 }
308
SkipNotify(DisplayState targetState)309 bool ScreenController::SkipNotify(DisplayState targetState)
310 {
311 bool isScreenOn = state_ == DisplayState::DISPLAY_ON || state_ == DisplayState::DISPLAY_DIM;
312 bool isTargetStateOn = targetState == DisplayState::DISPLAY_ON || targetState == DisplayState::DISPLAY_DIM;
313 return isScreenOn == isTargetStateOn;
314 }
315
CanSetBrightness()316 bool ScreenController::CanSetBrightness()
317 {
318 bool isScreenOn = IsScreenOn();
319 bool isOverridden = IsBrightnessOverridden();
320 bool isBoosted = IsBrightnessBoosted();
321 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "isScreenOn: %{public}d, isOverridden: %{public}d, isBoosted: %{public}d",
322 isScreenOn, isOverridden, isBoosted);
323 return isScreenOn && !isOverridden && !isBoosted;
324 }
325
CanDiscountBrightness()326 bool ScreenController::CanDiscountBrightness()
327 {
328 return IsScreenOn();
329 }
330
CanOverrideBrightness()331 bool ScreenController::CanOverrideBrightness()
332 {
333 return IsScreenOn() && !IsBrightnessBoosted();
334 }
335
CanBoostBrightness()336 bool ScreenController::CanBoostBrightness()
337 {
338 return IsScreenOn() && !IsBrightnessOverridden();
339 }
340
UpdateBrightness(uint32_t value,uint32_t gradualDuration,bool updateSetting)341 bool ScreenController::UpdateBrightness(uint32_t value, uint32_t gradualDuration, bool updateSetting)
342 {
343 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Update brightness, value=%{public}u, discount=%{public}lf,"\
344 " duration=%{public}u, updateSetting=%{public}d", value, discount_, gradualDuration, updateSetting);
345
346 if (animator_->IsAnimating()) {
347 animator_->StopAnimation();
348 }
349 if (gradualDuration > 0) {
350 animator_->StartAnimation(GetSettingBrightness(), value, gradualDuration);
351 return true;
352 }
353 auto brightness = DisplayPowerMgrService::GetSafeBrightness(static_cast<uint32_t>(value * discount_));
354 bool isSucc = action_->SetBrightness(brightness);
355 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Updated brightness is %{public}s, brightness: %{public}u",
356 isSucc ? "succ" : "failed", brightness);
357 if (isSucc && updateSetting) {
358 FFRTUtils::SubmitTask([this, value] { this->SetSettingBrightness(value); });
359 }
360 return isSucc;
361 }
362
GetSettingBrightness(const std::string & key) const363 uint32_t ScreenController::GetSettingBrightness(const std::string& key) const
364 {
365 uint32_t settingBrightness;
366 auto ret = DisplaySettingHelper::GetSettingBrightness(settingBrightness, key);
367 if (ret != ERR_OK) {
368 DISPLAY_HILOGW(FEAT_BRIGHTNESS,
369 "get setting brightness failed, return cachedBrightness_=%{public}u, key=%{public}s, ret=%{public}d",
370 cachedSettingBrightness_.load(), key.c_str(), ret);
371 return cachedSettingBrightness_;
372 }
373 return settingBrightness;
374 }
375
SetSettingBrightness(uint32_t value)376 void ScreenController::SetSettingBrightness(uint32_t value)
377 {
378 DisplaySettingHelper::SetSettingBrightness(value);
379 cachedSettingBrightness_ = value;
380 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "set setting brightness=%{public}u", value);
381 }
382
GetScreenOnBrightness() const383 uint32_t ScreenController::GetScreenOnBrightness() const
384 {
385 if (IsBrightnessBoosted()) {
386 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is boosted, return max brightness");
387 return DisplayParamHelper::GetMaxBrightness();
388 } else if (IsBrightnessOverridden()) {
389 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is overridden, return overridden brightness=%{public}u",
390 overriddenBrightness_);
391 return overriddenBrightness_;
392 } else {
393 return GetSettingBrightness();
394 }
395 }
396
RegisterSettingBrightnessObserver()397 void ScreenController::RegisterSettingBrightnessObserver()
398 {
399 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { BrightnessSettingUpdateFunc(key); };
400 DisplaySettingHelper::RegisterSettingBrightnessObserver(updateFunc);
401 }
402
BrightnessSettingUpdateFunc(const string & key)403 void ScreenController::BrightnessSettingUpdateFunc(const string& key)
404 {
405 if (animator_->IsAnimating() || !CanSetBrightness()) {
406 return;
407 }
408 uint32_t settingBrightness = GetSettingBrightness(key);
409 if (cachedSettingBrightness_ == settingBrightness) {
410 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "no need to set setting brightness");
411 return;
412 }
413 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "noset setting brightness updated, brightness %{public}u -> %{public}u",
414 cachedSettingBrightness_.load(), settingBrightness);
415 cachedSettingBrightness_ = settingBrightness;
416 }
417
UnregisterSettingBrightnessObserver()418 void ScreenController::UnregisterSettingBrightnessObserver()
419 {
420 DisplaySettingHelper::UnregisterSettingBrightnessObserver();
421 }
422
GetDiscount() const423 double ScreenController::GetDiscount() const
424 {
425 return discount_;
426 }
427
GetAnimationUpdateTime() const428 uint32_t ScreenController::GetAnimationUpdateTime() const
429 {
430 return animator_->GetAnimationUpdateTime();
431 }
432
SetCoordinated(bool coordinated)433 void ScreenController::SetCoordinated(bool coordinated)
434 {
435 action_->SetCoordinated(coordinated);
436 }
437 } // namespace DisplayPowerMgr
438 } // namespace OHOS
439