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 "refbase.h"
20 #include "display_power_mgr_service.h"
21 #include "display_param_helper.h"
22 #include "setting_provider.h"
23 #include "system_ability_definition.h"
24 #include "display_common.h"
25 #include "display_log.h"
26
27 using namespace std;
28 using namespace OHOS::PowerMgr;
29
30 namespace OHOS {
31 namespace DisplayPowerMgr {
32 namespace {
33 sptr<SettingObserver> g_brightnessObserver;
34 }
35
ScreenController(uint32_t displayId,const shared_ptr<DisplayEventHandler> & handler)36 ScreenController::ScreenController(uint32_t displayId, const shared_ptr<DisplayEventHandler>& handler)
37 : handler_(handler)
38 {
39 DISPLAY_HILOGI(COMP_SVC, "ScreenController created for displayId=%{public}u", displayId);
40 action_ = make_shared<ScreenAction>(displayId);
41 state_ = action_->GetDisplayState();
42
43 string name = "BrightnessController_" + to_string(displayId);
44 if (animateCallback_ == nullptr) {
45 animateCallback_ = make_shared<AnimateCallbackImpl>(action_, handler_);
46 }
47 animator_ = make_shared<GradualAnimator>(name, animateCallback_);
48
49 DisplayEventHandler::EventCallback cancelBoostCallback = [&](int64_t) { CancelBoostBrightness(); };
50 handler_->EmplaceCallBack(DisplayEventHandler::Event::EVENT_CANCEL_BOOST_BRIGHTNESS, cancelBoostCallback);
51 DisplayEventHandler::EventCallback setSettingBrightnessCallback =
52 [&](int64_t brightness) { SetSettingBrightness(static_cast<uint32_t>(brightness)); };
53 handler->EmplaceCallBack(DisplayEventHandler::Event::EVENT_SET_SETTING_BRIGHTNESS, setSettingBrightnessCallback);
54 }
55
AnimateCallbackImpl(const shared_ptr<ScreenAction> & action,const std::shared_ptr<DisplayEventHandler> & handler)56 ScreenController::AnimateCallbackImpl::AnimateCallbackImpl(const shared_ptr <ScreenAction>& action,
57 const std::shared_ptr<DisplayEventHandler>& handler)
58 : action_(action), handler_(handler)
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 auto brightness = DisplayPowerMgrService::GetSafeBrightness(static_cast<uint32_t>(currentValue * discount_));
69 bool isSucc = action_->SetBrightness(brightness);
70 if (isSucc) {
71 handler_->SendImmediateEvent(DisplayEventHandler::Event::EVENT_SET_SETTING_BRIGHTNESS, currentValue);
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
UpdateState(DisplayState state,uint32_t reason)93 bool ScreenController::UpdateState(DisplayState state, uint32_t reason)
94 {
95 DISPLAY_HILOGI(FEAT_STATE, "UpdateState, state=%{public}u, current state=%{public}u",
96 static_cast<uint32_t>(state), static_cast<uint32_t>(state_));
97 RETURN_IF_WITH_RET(state == state_, true);
98
99 switch (state) {
100 case DisplayState::DISPLAY_ON:
101 case DisplayState::DISPLAY_OFF: {
102 function<void(DisplayState)> callback = bind(&ScreenController::OnStateChanged, this, placeholders::_1);
103 bool ret = action_->SetDisplayState(state, callback);
104 if (!ret) {
105 DISPLAY_HILOGW(FEAT_STATE, "SetDisplayState failed state=%{public}d", state);
106 return ret;
107 }
108 break;
109 }
110 case DisplayState::DISPLAY_DIM:
111 case DisplayState::DISPLAY_SUSPEND: {
112 bool ret = action_->SetDisplayPower(state, stateChangeReason_);
113 if (!ret) {
114 DISPLAY_HILOGW(FEAT_STATE, "SetDisplayPower failed state=%{public}d", state);
115 return ret;
116 }
117 break;
118 }
119 default:
120 break;
121 }
122
123 lock_guard lock(mutexState_);
124 state_ = state;
125 stateChangeReason_ = reason;
126
127 DISPLAY_HILOGI(FEAT_STATE, "Update screen state to %{public}u", state);
128 return true;
129 }
130
IsScreenOn()131 bool ScreenController::IsScreenOn()
132 {
133 lock_guard lock(mutexState_);
134 return (state_ == DisplayState::DISPLAY_ON || state_ == DisplayState::DISPLAY_DIM);
135 }
136
SetBrightness(uint32_t value,uint32_t gradualDuration)137 bool ScreenController::SetBrightness(uint32_t value, uint32_t gradualDuration)
138 {
139 if (!CanSetBrightness()) {
140 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot set brightness, ignore the change");
141 return false;
142 }
143 return UpdateBrightness(value, gradualDuration, true);
144 }
145
GetBrightness()146 uint32_t ScreenController::GetBrightness()
147 {
148 return GetSettingBrightness();
149 }
150
GetDeviceBrightness()151 uint32_t ScreenController::GetDeviceBrightness()
152 {
153 return action_->GetBrightness();
154 }
155
DiscountBrightness(double discount,uint32_t gradualDuration)156 bool ScreenController::DiscountBrightness(double discount, uint32_t gradualDuration)
157 {
158 if (!CanDiscountBrightness()) {
159 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot discount brightness, ignore the change");
160 return false;
161 }
162 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Discount brightness, discount=%{public}lf", discount);
163 discount_ = discount;
164 if (animateCallback_) {
165 animateCallback_->DiscountBrightness(discount);
166 }
167 uint32_t screenOnBrightness = GetScreenOnBrightness();
168 return UpdateBrightness(screenOnBrightness, gradualDuration);
169 }
170
OverrideBrightness(uint32_t value,uint32_t gradualDuration)171 bool ScreenController::OverrideBrightness(uint32_t value, uint32_t gradualDuration)
172 {
173 if (!CanOverrideBrightness()) {
174 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot override brightness, ignore the change");
175 return false;
176 }
177 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Override brightness, value=%{public}u", value);
178 if (!isBrightnessOverridden_) {
179 isBrightnessOverridden_ = true;
180 }
181 overriddenBrightness_ = value;
182 return UpdateBrightness(value, gradualDuration);
183 }
184
RestoreBrightness(uint32_t gradualDuration)185 bool ScreenController::RestoreBrightness(uint32_t gradualDuration)
186 {
187 if (!IsBrightnessOverridden()) {
188 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is not override, no need to restore");
189 return false;
190 }
191 isBrightnessOverridden_ = false;
192 uint32_t settingBrightness = GetSettingBrightness();
193 return UpdateBrightness(settingBrightness, gradualDuration);
194 }
195
IsBrightnessOverridden() const196 bool ScreenController::IsBrightnessOverridden() const
197 {
198 return isBrightnessOverridden_;
199 }
200
BoostBrightness(uint32_t timeoutMs,uint32_t gradualDuration)201 bool ScreenController::BoostBrightness(uint32_t timeoutMs, uint32_t gradualDuration)
202 {
203 if (!CanBoostBrightness()) {
204 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot boost brightness, ignore the change");
205 return false;
206 }
207 bool ret = true;
208 if (!isBrightnessBoosted_) {
209 uint32_t maxBrightness = DisplayParamHelper::GetMaxBrightness();
210 DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Boost brightness, maxBrightness: %{public}d", maxBrightness);
211 isBrightnessBoosted_ = true;
212 ret = UpdateBrightness(maxBrightness, gradualDuration);
213 }
214
215 // If boost multi-times, we will resend the cancel boost event.
216 handler_->RemoveEvent(DisplayEventHandler::Event::EVENT_CANCEL_BOOST_BRIGHTNESS);
217 handler_->SendEvent(DisplayEventHandler::Event::EVENT_CANCEL_BOOST_BRIGHTNESS, static_cast<int64_t>(timeoutMs));
218 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "BoostBrightness update timeout=%{public}u, ret=%{public}d", timeoutMs, ret);
219 return ret;
220 }
221
CancelBoostBrightness(uint32_t gradualDuration)222 bool ScreenController::CancelBoostBrightness(uint32_t gradualDuration)
223 {
224 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Cancel boost brightness");
225 if (!IsBrightnessBoosted()) {
226 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is not boost, no need to restore");
227 return false;
228 }
229 handler_->RemoveEvent(DisplayEventHandler::Event::EVENT_CANCEL_BOOST_BRIGHTNESS);
230 isBrightnessBoosted_ = false;
231 uint32_t settingBrightness = GetSettingBrightness();
232 return UpdateBrightness(settingBrightness, gradualDuration);
233 }
234
IsBrightnessBoosted() const235 bool ScreenController::IsBrightnessBoosted() const
236 {
237 return isBrightnessBoosted_;
238 }
239
OnStateChanged(DisplayState state)240 void ScreenController::OnStateChanged(DisplayState state)
241 {
242 auto pms = DelayedSpSingleton<DisplayPowerMgrService>::GetInstance();
243 if (pms == nullptr) {
244 DISPLAY_HILOGW(FEAT_STATE, "pms is nullptr");
245 return;
246 }
247
248 bool ret = action_->SetDisplayPower(state, stateChangeReason_);
249 if (state == DisplayState::DISPLAY_ON) {
250 // Restore the brightness before screen off
251 uint32_t screenOnBrightness = GetScreenOnBrightness();
252 UpdateBrightness(screenOnBrightness);
253 }
254
255 if (ret) {
256 pms->NotifyStateChangeCallback(action_->GetDisplayId(), state);
257 }
258 }
259
CanSetBrightness()260 bool ScreenController::CanSetBrightness()
261 {
262 bool isScreenOn = IsScreenOn();
263 bool isOverridden = IsBrightnessOverridden();
264 bool isBoosted = IsBrightnessBoosted();
265 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "isScreenOn: %{public}d, isOverridden: %{public}d, isBoosted: %{public}d",
266 isScreenOn, isOverridden, isBoosted);
267 return isScreenOn && !isOverridden && !isBoosted;
268 }
269
CanDiscountBrightness()270 bool ScreenController::CanDiscountBrightness()
271 {
272 return IsScreenOn();
273 }
274
CanOverrideBrightness()275 bool ScreenController::CanOverrideBrightness()
276 {
277 return IsScreenOn() && !IsBrightnessBoosted();
278 }
279
CanBoostBrightness()280 bool ScreenController::CanBoostBrightness()
281 {
282 return IsScreenOn() && !IsBrightnessOverridden();
283 }
284
UpdateBrightness(uint32_t value,uint32_t gradualDuration,bool updateSetting)285 bool ScreenController::UpdateBrightness(uint32_t value, uint32_t gradualDuration, bool updateSetting)
286 {
287 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Update brightness, value=%{public}u, discount=%{public}lf,"\
288 " duration=%{public}u, updateSetting=%{public}d", value, discount_, gradualDuration, updateSetting);
289
290 if (animator_->IsAnimating()) {
291 animator_->StopAnimation();
292 }
293 if (gradualDuration > 0) {
294 animator_->StartAnimation(GetSettingBrightness(), value, gradualDuration);
295 return true;
296 }
297 auto brightness = DisplayPowerMgrService::GetSafeBrightness(static_cast<uint32_t>(value * discount_));
298 bool isSucc = action_->SetBrightness(brightness);
299 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Updated brightness is %{public}s, brightness: %{public}u",
300 isSucc ? "succ" : "failed", brightness);
301 if (isSucc && updateSetting) {
302 handler_->SendImmediateEvent(DisplayEventHandler::Event::EVENT_SET_SETTING_BRIGHTNESS,
303 static_cast<int64_t>(value));
304 }
305 return isSucc;
306 }
307
GetSettingBrightness(const std::string & key) const308 uint32_t ScreenController::GetSettingBrightness(const std::string& key) const
309 {
310 SettingProvider& provider = SettingProvider::GetInstance(DISPLAY_MANAGER_SERVICE_ID);
311 int32_t value;
312 ErrCode ret = provider.GetIntValue(key, value);
313 if (ret != ERR_OK) {
314 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "get setting brightness failed, return cachedBrightness_=%{public}u,"\
315 " key=%{public}s, ret=%{public}d", cachedSettingBrightness_, key.c_str(), ret);
316 return cachedSettingBrightness_;
317 }
318 return static_cast<uint32_t>(value);
319 }
320
SetSettingBrightness(uint32_t value)321 void ScreenController::SetSettingBrightness(uint32_t value)
322 {
323 uint32_t settingBrightness = GetSettingBrightness();
324 if (value == static_cast<uint32_t>(settingBrightness)) {
325 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "no need to set setting brightness");
326 return;
327 }
328 SettingProvider& provider = SettingProvider::GetInstance(DISPLAY_MANAGER_SERVICE_ID);
329 ErrCode ret = provider.PutIntValue(SETTING_BRIGHTNESS_KEY, static_cast<int32_t>(value));
330 if (ret != ERR_OK) {
331 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "set setting brightness failed, ret=%{public}d", ret);
332 return;
333 }
334 cachedSettingBrightness_ = value;
335 }
336
GetScreenOnBrightness() const337 uint32_t ScreenController::GetScreenOnBrightness() const
338 {
339 if (IsBrightnessBoosted()) {
340 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is boosted, return max brightness");
341 return DisplayParamHelper::GetMaxBrightness();
342 } else if (IsBrightnessOverridden()) {
343 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness is overridden, return overridden brightness=%{public}u",
344 overriddenBrightness_);
345 return overriddenBrightness_;
346 } else {
347 return GetSettingBrightness();
348 }
349 }
350
RegisterSettingBrightnessObserver()351 void ScreenController::RegisterSettingBrightnessObserver()
352 {
353 if (g_brightnessObserver) {
354 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "setting brightness observer is already registered");
355 return;
356 }
357 SettingProvider& provider = SettingProvider::GetInstance(DISPLAY_MANAGER_SERVICE_ID);
358 SettingObserver::UpdateFunc updateFunc = [&](const std::string& key) { BrightnessSettingUpdateFunc(key); };
359 g_brightnessObserver = provider.CreateObserver(SETTING_BRIGHTNESS_KEY, updateFunc);
360 ErrCode ret = provider.RegisterObserver(g_brightnessObserver);
361 if (ret != ERR_OK) {
362 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "register setting brightness observer failed, ret=%{public}d", ret);
363 g_brightnessObserver = nullptr;
364 }
365 }
366
BrightnessSettingUpdateFunc(const string & key)367 void ScreenController::BrightnessSettingUpdateFunc(const string& key)
368 {
369 if (animator_->IsAnimating() || !CanSetBrightness()) {
370 return;
371 }
372 uint32_t settingBrightness = GetSettingBrightness(key);
373 if (cachedSettingBrightness_ == settingBrightness) {
374 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "no need to set setting brightness");
375 return;
376 }
377 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "setting brightness updated, brightness %{public}u -> %{public}u",
378 cachedSettingBrightness_, settingBrightness);
379 cachedSettingBrightness_ = settingBrightness;
380 UpdateBrightness(settingBrightness);
381 }
382
UnregisterSettingBrightnessObserver()383 void ScreenController::UnregisterSettingBrightnessObserver()
384 {
385 if (g_brightnessObserver == nullptr) {
386 DISPLAY_HILOGD(FEAT_BRIGHTNESS, "g_brightnessObserver is nullptr, no need to unregister");
387 return;
388 }
389 SettingProvider& provider = SettingProvider::GetInstance(DISPLAY_MANAGER_SERVICE_ID);
390 ErrCode ret = provider.UnregisterObserver(g_brightnessObserver);
391 if (ret != ERR_OK) {
392 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "unregister setting brightness observer failed, ret=%{public}d", ret);
393 }
394 g_brightnessObserver = nullptr;
395 }
396
GetDiscount() const397 double ScreenController::GetDiscount() const
398 {
399 return discount_;
400 }
401
GetAnimationUpdateTime() const402 uint32_t ScreenController::GetAnimationUpdateTime() const
403 {
404 return animator_->GetAnimationUpdateTime();
405 }
406 } // namespace DisplayPowerMgr
407 } // namespace OHOS
408