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