• 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 "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