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