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