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