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