• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "power_state_machine.h"
17 
18 #include <cinttypes>
19 #include <datetime_ex.h>
20 #include <hisysevent.h>
21 
22 #include "hitrace_meter.h"
23 #include "power_mgr_factory.h"
24 #include "power_mgr_service.h"
25 #include "ffrt_utils.h"
26 #include "setting_helper.h"
27 
28 namespace OHOS {
29 namespace PowerMgr {
30 namespace {
31 sptr<SettingObserver> g_displayOffTimeObserver;
32 FFRTQueue g_queue("power_state_machine");
33 FFRTHandle g_userActivityTimeoutHandle;
34 }
PowerStateMachine(const wptr<PowerMgrService> & pms)35 PowerStateMachine::PowerStateMachine(const wptr<PowerMgrService>& pms) : pms_(pms), currentState_(PowerState::UNKNOWN)
36 {
37     POWER_HILOGD(FEATURE_POWER_STATE, "Instance start");
38     // NOTICE Need get screen state when device startup,
39     // rightnow we set screen is on as default
40     mDeviceState_.screenState.lastOnTime = GetTickCount();
41     mDeviceState_.screenState.lastOffTime = 0;
42     mDeviceState_.lastWakeupEventTime = 0;
43     mDeviceState_.lastRefreshActivityTime = 0;
44     mDeviceState_.lastWakeupDeviceTime = 0;
45     mDeviceState_.lastSuspendDeviceTime = 0;
46 
47     // init lock map which will block state transit
48     std::vector<RunningLockType> awakeBlocker {};
49     std::vector<RunningLockType> freezeBlocker {};
50     std::vector<RunningLockType> inactiveBlocker {RunningLockType::RUNNINGLOCK_SCREEN};
51     std::vector<RunningLockType> standByBlocker {};
52     std::vector<RunningLockType> dozeBlocker {};
53     std::vector<RunningLockType> sleepBlocker {RunningLockType::RUNNINGLOCK_BACKGROUND};
54     std::vector<RunningLockType> hibernateBlocker {};
55     std::vector<RunningLockType> shutdownBlocker {};
56 
57     lockMap_.emplace(PowerState::AWAKE, std::make_shared<std::vector<RunningLockType>>(awakeBlocker));
58     lockMap_.emplace(PowerState::FREEZE, std::make_shared<std::vector<RunningLockType>>(freezeBlocker));
59     lockMap_.emplace(PowerState::INACTIVE, std::make_shared<std::vector<RunningLockType>>(inactiveBlocker));
60     lockMap_.emplace(PowerState::STAND_BY, std::make_shared<std::vector<RunningLockType>>(standByBlocker));
61     lockMap_.emplace(PowerState::DOZE, std::make_shared<std::vector<RunningLockType>>(dozeBlocker));
62     lockMap_.emplace(PowerState::SLEEP, std::make_shared<std::vector<RunningLockType>>(sleepBlocker));
63     lockMap_.emplace(PowerState::HIBERNATE, std::make_shared<std::vector<RunningLockType>>(hibernateBlocker));
64     lockMap_.emplace(PowerState::SHUTDOWN, std::make_shared<std::vector<RunningLockType>>(shutdownBlocker));
65 
66     POWER_HILOGD(FEATURE_POWER_STATE, "Instance end");
67 }
68 
~PowerStateMachine()69 PowerStateMachine::~PowerStateMachine() {}
70 
Init()71 bool PowerStateMachine::Init()
72 {
73     POWER_HILOGD(FEATURE_POWER_STATE, "Start init");
74 
75     stateAction_ = PowerMgrFactory::GetDeviceStateAction();
76     InitStateMap();
77 
78     if (powerStateCBDeathRecipient_ == nullptr) {
79         powerStateCBDeathRecipient_ = new PowerStateCallbackDeathRecipient();
80     }
81     POWER_HILOGD(FEATURE_POWER_STATE, "Init success");
82     return true;
83 }
84 
InitState()85 void PowerStateMachine::InitState()
86 {
87     POWER_HILOGD(FEATURE_POWER_STATE, "Init power state");
88     if (IsScreenOn()) {
89         SetState(PowerState::AWAKE, StateChangeReason::STATE_CHANGE_REASON_INIT, true);
90     } else {
91         SetState(PowerState::INACTIVE, StateChangeReason::STATE_CHANGE_REASON_INIT, true);
92     }
93 }
94 
EmplaceAwake()95 void PowerStateMachine::EmplaceAwake()
96 {
97     controllerMap_.emplace(PowerState::AWAKE,
98         std::make_shared<StateController>(PowerState::AWAKE, shared_from_this(), [this](StateChangeReason reason) {
99             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_AWAKE lambda start");
100             mDeviceState_.screenState.lastOnTime = GetTickCount();
101             uint32_t ret = this->stateAction_->SetDisplayState(DisplayState::DISPLAY_ON, reason);
102             // Display power service maybe not ready when init
103             if (ret != ActionResult::SUCCESS && reason != StateChangeReason::STATE_CHANGE_REASON_INIT) {
104                 POWER_HILOGE(FEATURE_POWER_STATE, "Failed to go to AWAKE, display error, ret: %{public}u", ret);
105                 return TransitResult::DISPLAY_ON_ERR;
106             }
107             ResetInactiveTimer();
108             return TransitResult::SUCCESS;
109         }));
110 }
111 
EmplaceFreeze()112 void PowerStateMachine::EmplaceFreeze()
113 {
114     controllerMap_.emplace(PowerState::FREEZE,
115         std::make_shared<StateController>(PowerState::FREEZE, shared_from_this(), [this](StateChangeReason reason) {
116             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_FREEZE lambda start");
117             // Subsequent added functions
118             return TransitResult::SUCCESS;
119         }));
120 }
121 
EmplaceInactive()122 void PowerStateMachine::EmplaceInactive()
123 {
124     controllerMap_.emplace(PowerState::INACTIVE,
125         std::make_shared<StateController>(PowerState::INACTIVE, shared_from_this(), [this](StateChangeReason reason) {
126             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_INACTIVE lambda start");
127             mDeviceState_.screenState.lastOffTime = GetTickCount();
128             DisplayState state = DisplayState::DISPLAY_OFF;
129             if (enableDisplaySuspend_) {
130                 POWER_HILOGI(FEATURE_POWER_STATE, "Display suspend enabled");
131                 state = DisplayState::DISPLAY_SUSPEND;
132             }
133             uint32_t ret = this->stateAction_->SetDisplayState(state, reason);
134             // Display power service maybe not ready when init
135             if (ret != ActionResult::SUCCESS && reason != StateChangeReason::STATE_CHANGE_REASON_INIT) {
136                 POWER_HILOGE(FEATURE_POWER_STATE, "Failed to go to INACTIVE, display error, ret: %{public}u", ret);
137                 return TransitResult::DISPLAY_OFF_ERR;
138             }
139             return TransitResult::SUCCESS;
140         }));
141 }
142 
EmplaceStandBy()143 void PowerStateMachine::EmplaceStandBy()
144 {
145     controllerMap_.emplace(PowerState::STAND_BY,
146         std::make_shared<StateController>(PowerState::STAND_BY, shared_from_this(), [this](StateChangeReason reason) {
147             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_STAND_BY lambda start");
148             mDeviceState_.screenState.lastOffTime = GetTickCount();
149             // Subsequent added functions
150             return TransitResult::SUCCESS;
151         }));
152 }
153 
EmplaceDoze()154 void PowerStateMachine::EmplaceDoze()
155 {
156     controllerMap_.emplace(PowerState::DOZE,
157         std::make_shared<StateController>(PowerState::DOZE, shared_from_this(), [this](StateChangeReason reason) {
158             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_DOZE lambda start");
159             mDeviceState_.screenState.lastOffTime = GetTickCount();
160             // Subsequent added functions
161             return TransitResult::SUCCESS;
162         }));
163 }
164 
EmplaceSleep()165 void PowerStateMachine::EmplaceSleep()
166 {
167     controllerMap_.emplace(PowerState::SLEEP,
168         std::make_shared<StateController>(PowerState::SLEEP, shared_from_this(), [this](StateChangeReason reason) {
169             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_SLEEP lambda start");
170             return TransitResult::SUCCESS;
171         }));
172 }
173 
EmplaceHibernate()174 void PowerStateMachine::EmplaceHibernate()
175 {
176     controllerMap_.emplace(PowerState::HIBERNATE,
177         std::make_shared<StateController>(PowerState::HIBERNATE, shared_from_this(), [this](StateChangeReason reason) {
178             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_HIBERNATE lambda start");
179             // Subsequent added functions
180             return TransitResult::SUCCESS;
181         }));
182 }
183 
EmplaceShutdown()184 void PowerStateMachine::EmplaceShutdown()
185 {
186     controllerMap_.emplace(PowerState::SHUTDOWN,
187         std::make_shared<StateController>(PowerState::SHUTDOWN, shared_from_this(), [this](StateChangeReason reason) {
188             POWER_HILOGI(FEATURE_POWER_STATE, "StateController_SHUTDOWN lambda start");
189             // Subsequent added functions
190             return TransitResult::SUCCESS;
191         }));
192 }
193 
InitStateMap()194 void PowerStateMachine::InitStateMap()
195 {
196     EmplaceAwake();
197     EmplaceFreeze();
198     EmplaceInactive();
199     EmplaceStandBy();
200     EmplaceDoze();
201     EmplaceSleep();
202     EmplaceHibernate();
203     EmplaceShutdown();
204 }
205 
onSuspend()206 void PowerStateMachine::onSuspend()
207 {
208     POWER_HILOGI(FEATURE_SUSPEND, "System is suspending");
209 }
210 
onWakeup()211 void PowerStateMachine::onWakeup()
212 {
213     POWER_HILOGI(FEATURE_WAKEUP, "System is awaking");
214     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
215     if (pms == nullptr) {
216         return;
217     }
218     FFRTTask task = [&pms] {
219         pms->GetPowerStateMachine()->HandleSystemWakeup();
220     };
221 }
222 
SuspendDeviceInner(pid_t pid,int64_t callTimeMs,SuspendDeviceType type,bool suspendImmed,bool ignoreScreenState)223 void PowerStateMachine::SuspendDeviceInner(
224     pid_t pid, int64_t callTimeMs, SuspendDeviceType type, bool suspendImmed, bool ignoreScreenState)
225 {
226     StartTrace(HITRACE_TAG_POWER, "SuspendDevice");
227     if (type > SuspendDeviceType::SUSPEND_DEVICE_REASON_MAX) {
228         POWER_HILOGW(FEATURE_SUSPEND, "Invalid type: %{public}d", type);
229         return;
230     }
231     // Check the screen state
232     if (!ignoreScreenState) {
233         if (stateAction_ != nullptr) {
234             stateAction_->Suspend(
235                 callTimeMs, type, suspendImmed ? SUSPEND_DEVICE_IMMEDIATELY : SUSPEND_DEVICE_NEED_DOZE);
236         }
237         mDeviceState_.lastSuspendDeviceTime = callTimeMs;
238         POWER_HILOGD(FEATURE_SUSPEND, "Suspend device success");
239     } else {
240         POWER_HILOGD(FEATURE_SUSPEND, "Do not suspend device, screen state is ignored");
241     }
242 
243     SetState(PowerState::INACTIVE, GetReasionBySuspendType(type), true);
244     FinishTrace(HITRACE_TAG_POWER);
245     POWER_HILOGD(FEATURE_SUSPEND, "Suspend device finish");
246 }
247 
WakeupDeviceInner(pid_t pid,int64_t callTimeMs,WakeupDeviceType type,const std::string & details,const std::string & pkgName)248 void PowerStateMachine::WakeupDeviceInner(
249     pid_t pid, int64_t callTimeMs, WakeupDeviceType type, const std::string& details, const std::string& pkgName)
250 {
251     StartTrace(HITRACE_TAG_POWER, "WakeupDevice");
252     if (type > WakeupDeviceType::WAKEUP_DEVICE_MAX) {
253         POWER_HILOGW(FEATURE_WAKEUP, "Invalid type: %{public}d", type);
254         return;
255     }
256     // Call legacy wakeup, Check the screen state
257     if (stateAction_ != nullptr) {
258         stateAction_->Wakeup(callTimeMs, type, details, pkgName);
259     }
260     mDeviceState_.lastWakeupDeviceTime = callTimeMs;
261 
262     ResetInactiveTimer();
263     SetState(PowerState::AWAKE, GetReasonByWakeType(type), true);
264 
265     FinishTrace(HITRACE_TAG_POWER);
266     POWER_HILOGD(FEATURE_WAKEUP, "Wakeup device finish");
267 }
268 
RefreshActivityInner(pid_t pid,int64_t callTimeMs,UserActivityType type,bool needChangeBacklight)269 void PowerStateMachine::RefreshActivityInner(
270     pid_t pid, int64_t callTimeMs, UserActivityType type, bool needChangeBacklight)
271 {
272     if (type > UserActivityType::USER_ACTIVITY_TYPE_MAX) {
273         POWER_HILOGW(FEATURE_ACTIVITY, "Invalid type: %{public}d", type);
274         return;
275     }
276     // Check the screen state
277     if (IsScreenOn()) {
278         if (stateAction_ != nullptr) {
279             stateAction_->RefreshActivity(callTimeMs, type,
280                 needChangeBacklight ? REFRESH_ACTIVITY_NEED_CHANGE_LIGHTS : REFRESH_ACTIVITY_NO_CHANGE_LIGHTS);
281             mDeviceState_.screenState.lastOnTime = GetTickCount();
282         }
283         // reset timer
284         ResetInactiveTimer();
285     } else {
286         POWER_HILOGD(FEATURE_ACTIVITY, "Ignore refresh activity, screen is off");
287     }
288 }
289 
CheckRefreshTime()290 bool PowerStateMachine::CheckRefreshTime()
291 {
292     // The minimum refreshactivity interval is 100ms!!
293     int64_t now = GetTickCount();
294     if ((mDeviceState_.lastRefreshActivityTime + MIN_TIME_MS_BETWEEN_USERACTIVITIES) > now) {
295         return true;
296     }
297     mDeviceState_.lastRefreshActivityTime = now;
298     return false;
299 }
300 
OverrideScreenOffTimeInner(int64_t timeout)301 bool PowerStateMachine::OverrideScreenOffTimeInner(int64_t timeout)
302 {
303     POWER_HILOGD(COMP_SVC, "Override screenOffTime, timeout=%{public}" PRId64 "", timeout);
304     if (!isScreenOffTimeOverride_) {
305         int64_t beforeOverrideTime = this->GetDisplayOffTime();
306         isScreenOffTimeOverride_ = true;
307         beforeOverrideTime_ = beforeOverrideTime;
308     }
309     this->SetDisplayOffTime(timeout, false);
310     POWER_HILOGD(COMP_SVC, "Override screenOffTime finish");
311     return true;
312 }
313 
RestoreScreenOffTimeInner()314 bool PowerStateMachine::RestoreScreenOffTimeInner()
315 {
316     if (!isScreenOffTimeOverride_) {
317         POWER_HILOGD(COMP_SVC, "RestoreScreenOffTime is not override, no need to restore");
318         return false;
319     }
320     this->SetDisplayOffTime(beforeOverrideTime_, false);
321     isScreenOffTimeOverride_ = false;
322     POWER_HILOGD(COMP_SVC, "Restore screenOffTime finish");
323     return true;
324 }
325 
ForceSuspendDeviceInner(pid_t pid,int64_t callTimeMs)326 bool PowerStateMachine::ForceSuspendDeviceInner(pid_t pid, int64_t callTimeMs)
327 {
328     SetState(
329         PowerState::INACTIVE, GetReasionBySuspendType(SuspendDeviceType::SUSPEND_DEVICE_REASON_FORCE_SUSPEND), true);
330     if (stateAction_ != nullptr) {
331         currentState_ = PowerState::SLEEP;
332         stateAction_->GoToSleep(onSuspend, onWakeup, true);
333     }
334 
335     POWER_HILOGI(FEATURE_SUSPEND, "Force suspend finish");
336     return true;
337 }
338 
IsScreenOn()339 bool PowerStateMachine::IsScreenOn()
340 {
341     DisplayState state = stateAction_->GetDisplayState();
342     if (state == DisplayState::DISPLAY_ON || state == DisplayState::DISPLAY_DIM) {
343         POWER_HILOGD(FEATURE_POWER_STATE, "Current screen is on, state: %{public}u", state);
344         return true;
345     }
346     POWER_HILOGD(FEATURE_POWER_STATE, "Current screen is off, state: %{public}u", state);
347     return false;
348 }
349 
ReceiveScreenEvent(bool isScreenOn)350 void PowerStateMachine::ReceiveScreenEvent(bool isScreenOn)
351 {
352     POWER_HILOGD(FEATURE_POWER_STATE, "Enter");
353     std::lock_guard lock(mutex_);
354     auto prestate = mDeviceState_.screenState.state;
355     if (isScreenOn) {
356         mDeviceState_.screenState.lastOnTime = GetTickCount();
357     } else {
358         mDeviceState_.screenState.lastOffTime = GetTickCount();
359     }
360     if (prestate != mDeviceState_.screenState.state) {
361         NotifyPowerStateChanged(isScreenOn ? PowerState::AWAKE : PowerState::INACTIVE);
362     }
363 }
364 
RegisterPowerStateCallback(const sptr<IPowerStateCallback> & callback)365 void PowerStateMachine::RegisterPowerStateCallback(const sptr<IPowerStateCallback>& callback)
366 {
367     std::lock_guard lock(mutex_);
368     RETURN_IF(callback == nullptr);
369     auto object = callback->AsObject();
370     RETURN_IF(object == nullptr);
371     auto retIt = powerStateListeners_.insert(callback);
372     if (retIt.second) {
373         object->AddDeathRecipient(powerStateCBDeathRecipient_);
374     }
375     POWER_HILOGD(FEATURE_POWER_STATE, "listeners.size = %{public}d, insertOk = %{public}d",
376         static_cast<unsigned int>(powerStateListeners_.size()), retIt.second);
377 }
378 
UnRegisterPowerStateCallback(const sptr<IPowerStateCallback> & callback)379 void PowerStateMachine::UnRegisterPowerStateCallback(const sptr<IPowerStateCallback>& callback)
380 {
381     std::lock_guard lock(mutex_);
382     RETURN_IF(callback == nullptr);
383     auto object = callback->AsObject();
384     RETURN_IF(object == nullptr);
385     size_t eraseNum = powerStateListeners_.erase(callback);
386     if (eraseNum != 0) {
387         object->RemoveDeathRecipient(powerStateCBDeathRecipient_);
388     }
389     POWER_HILOGD(FEATURE_POWER_STATE, "listeners.size = %{public}d, eraseNum = %{public}zu",
390         static_cast<unsigned int>(powerStateListeners_.size()), eraseNum);
391 }
392 
GetReasonTypeString(StateChangeReason type)393 static const std::string GetReasonTypeString(StateChangeReason type)
394 {
395     switch (type) {
396         case StateChangeReason::STATE_CHANGE_REASON_INIT:
397             return std::string("INIT");
398         case StateChangeReason::STATE_CHANGE_REASON_TIMEOUT:
399             return std::string("TIMEOUT");
400         case StateChangeReason::STATE_CHANGE_REASON_RUNNING_LOCK:
401             return std::string("RUNNING_LOCK");
402         case StateChangeReason::STATE_CHANGE_REASON_BATTERY:
403             return std::string("BATTERY");
404         case StateChangeReason::STATE_CHANGE_REASON_THERMAL:
405             return std::string("THERMAL");
406         case StateChangeReason::STATE_CHANGE_REASON_WORK:
407             return std::string("WORK");
408         case StateChangeReason::STATE_CHANGE_REASON_SYSTEM:
409             return std::string("SYSTEM");
410         case StateChangeReason::STATE_CHANGE_REASON_APPLICATION:
411             return std::string("APPLICATION");
412         case StateChangeReason::STATE_CHANGE_REASON_SETTINGS:
413             return std::string("SETTINGS");
414         case StateChangeReason::STATE_CHANGE_REASON_HARD_KEY:
415             return std::string("HARD_KEY");
416         case StateChangeReason::STATE_CHANGE_REASON_TOUCH:
417             return std::string("TOUCH");
418         case StateChangeReason::STATE_CHANGE_REASON_CABLE:
419             return std::string("CABLE");
420         case StateChangeReason::STATE_CHANGE_REASON_SENSOR:
421             return std::string("SENSOR");
422         case StateChangeReason::STATE_CHANGE_REASON_LID:
423             return std::string("LID");
424         case StateChangeReason::STATE_CHANGE_REASON_CAMERA:
425             return std::string("CAMERA");
426         case StateChangeReason::STATE_CHANGE_REASON_ACCESSIBILITY:
427             return std::string("ACCESS");
428         case StateChangeReason::STATE_CHANGE_REASON_POWER_KEY:
429             return std::string("POWER_KEY");
430         case StateChangeReason::STATE_CHANGE_REASON_KEYBOARD:
431             return std::string("KEYBOARD");
432         case StateChangeReason::STATE_CHANGE_REASON_MOUSE:
433             return std::string("MOUSE");
434         case StateChangeReason::STATE_CHANGE_REASON_REMOTE:
435             return std::string("REMOTE");
436         case StateChangeReason::STATE_CHANGE_REASON_UNKNOWN:
437             return std::string("UNKNOWN");
438         default:
439             break;
440     }
441 
442     return std::string("UNKNOWN");
443 }
444 
GetPowerStateString(PowerState state)445 static const std::string GetPowerStateString(PowerState state)
446 {
447     switch (state) {
448         case PowerState::AWAKE:
449             return std::string("AWAKE");
450         case PowerState::FREEZE:
451             return std::string("FREEZE");
452         case PowerState::INACTIVE:
453             return std::string("INACTIVE");
454         case PowerState::STAND_BY:
455             return std::string("STAND_BY");
456         case PowerState::DOZE:
457             return std::string("DOZE");
458         case PowerState::SLEEP:
459             return std::string("SLEEP");
460         case PowerState::HIBERNATE:
461             return std::string("HIBERNATE");
462         case PowerState::SHUTDOWN:
463             return std::string("SHUTDOWN");
464         case PowerState::UNKNOWN:
465             return std::string("UNKNOWN");
466         default:
467             break;
468     }
469 
470     return std::string("UNKNOWN");
471 }
472 
GetDisplayStateString(DisplayState state)473 static const std::string GetDisplayStateString(DisplayState state)
474 {
475     switch (state) {
476         case DisplayState::DISPLAY_OFF:
477             return std::string("DISPLAY_OFF");
478         case DisplayState::DISPLAY_DIM:
479             return std::string("DISPLAY_DIM");
480         case DisplayState::DISPLAY_ON:
481             return std::string("DISPLAY_ON");
482         case DisplayState::DISPLAY_SUSPEND:
483             return std::string("DISPLAY_SUSPEND");
484         case DisplayState::DISPLAY_UNKNOWN:
485             return std::string("DISPLAY_UNKNOWN");
486         default:
487             break;
488     }
489 
490     return std::string("DISPLAY_UNKNOWN");
491 }
492 
GetRunningLockTypeString(RunningLockType type)493 static const std::string GetRunningLockTypeString(RunningLockType type)
494 {
495     switch (type) {
496         case RunningLockType::RUNNINGLOCK_SCREEN:
497             return std::string("SCREEN");
498         case RunningLockType::RUNNINGLOCK_BACKGROUND:
499             return std::string("BACKGROUND");
500         case RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL:
501             return std::string("PROXIMITY_SCREEN_CONTROL");
502         case RunningLockType::RUNNINGLOCK_BUTT:
503             return std::string("BUTT");
504         default:
505             break;
506     }
507 
508     return std::string("UNKNOWN");
509 }
510 
EnableMock(IDeviceStateAction * mockAction)511 void PowerStateMachine::EnableMock(IDeviceStateAction* mockAction)
512 {
513     std::lock_guard lock(mutex_);
514     // reset to awake state when mock and default off/sleep time
515     currentState_ = PowerState::AWAKE;
516     displayOffTime_ = DEFAULT_DISPLAY_OFF_TIME;
517     sleepTime_ = DEFAULT_SLEEP_TIME;
518     ResetInactiveTimer();
519 
520     std::unique_ptr<IDeviceStateAction> mock(mockAction);
521     stateAction_.reset();
522     stateAction_ = std::move(mock);
523 }
524 
NotifyPowerStateChanged(PowerState state)525 void PowerStateMachine::NotifyPowerStateChanged(PowerState state)
526 {
527     POWER_HILOGI(
528         FEATURE_POWER_STATE, "state = %{public}u, listeners.size = %{public}zu", state, powerStateListeners_.size());
529     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "STATE", HiviewDFX::HiSysEvent::EventType::STATISTIC, "STATE",
530         static_cast<uint32_t>(state));
531     std::lock_guard lock(mutex_);
532     int64_t now = GetTickCount();
533     // Send Notification event
534     SendEventToPowerMgrNotify(state, now);
535 
536     // Call back all native function
537     for (auto& listener : powerStateListeners_) {
538         listener->OnPowerStateChanged(state);
539     }
540 }
541 
SendEventToPowerMgrNotify(PowerState state,int64_t callTime)542 void PowerStateMachine::SendEventToPowerMgrNotify(PowerState state, int64_t callTime)
543 {
544     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
545     if (pms == nullptr) {
546         POWER_HILOGE(FEATURE_POWER_STATE, "Pms is nullptr");
547         return;
548     }
549     auto notify = pms->GetPowerMgrNotify();
550     if (notify == nullptr) {
551         POWER_HILOGE(FEATURE_POWER_STATE, "Notify is null");
552         return;
553     }
554     if (state == PowerState::AWAKE) {
555         notify->PublishScreenOnEvents(callTime);
556     } else if (state == PowerState::INACTIVE) {
557         notify->PublishScreenOffEvents(callTime);
558     } else {
559         POWER_HILOGI(FEATURE_POWER_STATE, "No need to publish event, state:%{public}u", state);
560     }
561 }
562 
OnRemoteDied(const wptr<IRemoteObject> & remote)563 void PowerStateMachine::PowerStateCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
564 {
565     if (remote == nullptr || remote.promote() == nullptr) {
566         return;
567     }
568     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
569     if (pms == nullptr) {
570         POWER_HILOGE(FEATURE_POWER_STATE, "Pms is nullptr");
571         return;
572     }
573     sptr<IPowerStateCallback> callback = iface_cast<IPowerStateCallback>(remote.promote());
574     FFRTTask unRegFunc = [&] {
575         pms->UnRegisterPowerStateCallback(callback);
576     };
577     FFRTUtils::SubmitTask(unRegFunc);
578 }
579 
SetDelayTimer(int64_t delayTime,int32_t event)580 void PowerStateMachine::SetDelayTimer(int64_t delayTime, int32_t event)
581 {
582     POWER_HILOGD(FEATURE_ACTIVITY, "Set delay timer, delayTime=%{public}s, event=%{public}d",
583         std::to_string(delayTime).c_str(), event);
584     switch (event) {
585         case CHECK_USER_ACTIVITY_TIMEOUT_MSG: {
586             FFRTTask task = [this] {
587                 HandleActivityTimeout();
588             };
589             g_userActivityTimeoutHandle = FFRTUtils::SubmitDelayTask(task, delayTime, g_queue);
590             break;
591         }
592         case CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG: {
593             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
594             auto suspendController = pms->GetSuspendController();
595             if (suspendController == nullptr) {
596                 POWER_HILOGW(FEATURE_ACTIVITY, "suspendController is nullptr");
597                 return;
598             }
599             suspendController->HandleEvent(delayTime);
600             break;
601         }
602         default: {
603             break;
604         }
605     }
606 }
607 
CancelDelayTimer(int32_t event)608 void PowerStateMachine::CancelDelayTimer(int32_t event)
609 {
610     POWER_HILOGD(FEATURE_ACTIVITY, "Cancel delay timer, event: %{public}d", event);
611     switch (event) {
612         case CHECK_USER_ACTIVITY_TIMEOUT_MSG: {
613             FFRTUtils::CancelTask(g_userActivityTimeoutHandle, g_queue);
614             break;
615         }
616         case CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG: {
617             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
618             auto suspendController = pms->GetSuspendController();
619             if (suspendController == nullptr) {
620                 POWER_HILOGW(FEATURE_ACTIVITY, "suspendController is nullptr");
621                 return;
622             }
623             suspendController->CancelEvent();
624             break;
625         }
626         default: {
627             break;
628         }
629     }
630 }
631 
ResetInactiveTimer()632 void PowerStateMachine::ResetInactiveTimer()
633 {
634     CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
635     CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
636     if (this->GetDisplayOffTime() < 0) {
637         POWER_HILOGD(FEATURE_ACTIVITY, "Auto display off is disabled");
638         return;
639     }
640 
641     if (this->CheckRunningLock(PowerState::INACTIVE)) {
642         const double DIMTIMERATE = 2.0/3;
643         this->SetDelayTimer(
644             this->GetDisplayOffTime() * DIMTIMERATE, PowerStateMachine::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
645     }
646 }
647 
ResetSleepTimer()648 void PowerStateMachine::ResetSleepTimer()
649 {
650     CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
651     CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
652     if (this->GetSleepTime() < 0) {
653         POWER_HILOGD(FEATURE_ACTIVITY, "Auto sleep is disabled");
654         return;
655     }
656 }
657 
HandleActivityTimeout()658 void PowerStateMachine::HandleActivityTimeout()
659 {
660     POWER_HILOGD(FEATURE_ACTIVITY, "Enter, displayState = %{public}d", stateAction_->GetDisplayState());
661     DisplayState dispState = stateAction_->GetDisplayState();
662     const uint32_t THREE = 3;
663     if (!this->CheckRunningLock(PowerState::INACTIVE)) {
664         POWER_HILOGI(FEATURE_ACTIVITY, "RunningLock is blocking to transit to INACTIVE");
665         return;
666     }
667     if (dispState == DisplayState::DISPLAY_ON) {
668         stateAction_->SetDisplayState(DisplayState::DISPLAY_DIM, StateChangeReason::STATE_CHANGE_REASON_TIMEOUT);
669         if (this->GetDisplayOffTime() < 0) {
670             POWER_HILOGD(FEATURE_ACTIVITY, "Auto display off is disabled");
671             return;
672         } else {
673             SetDelayTimer(GetDisplayOffTime() / THREE, PowerStateMachine::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
674         }
675     } else {
676         POWER_HILOGW(FEATURE_ACTIVITY, "Display is not on, ignore activity timeout, state = %{public}d", dispState);
677         HandleActivityOffTimeout();
678     }
679 }
680 
HandleActivityOffTimeout()681 void PowerStateMachine::HandleActivityOffTimeout()
682 {
683     POWER_HILOGD(FEATURE_ACTIVITY, "Enter, displayState = %{public}d", stateAction_->GetDisplayState());
684     if (!this->CheckRunningLock(PowerState::INACTIVE)) {
685         POWER_HILOGI(FEATURE_POWER_STATE, "RunningLock is blocking to transit to INACTIVE");
686         return;
687     }
688     DisplayState dispState = stateAction_->GetDisplayState();
689     // Also transit state when ON if system not support DIM
690     if (dispState == DisplayState::DISPLAY_ON || dispState == DisplayState::DISPLAY_DIM) {
691         SetState(PowerState::INACTIVE, StateChangeReason::STATE_CHANGE_REASON_TIMEOUT);
692     } else {
693         POWER_HILOGW(FEATURE_ACTIVITY, "Display is off, ignore activity off timeout, state = %{public}d", dispState);
694     }
695 }
696 
HandleActivitySleepTimeout()697 void PowerStateMachine::HandleActivitySleepTimeout()
698 {
699     POWER_HILOGD(FEATURE_ACTIVITY, "Enter, displayState = %{public}d", stateAction_->GetDisplayState());
700     if (!this->CheckRunningLock(PowerState::SLEEP)) {
701         POWER_HILOGW(FEATURE_POWER_STATE, "RunningLock is blocking to transit to SLEEP");
702         return;
703     }
704     DisplayState dispState = stateAction_->GetDisplayState();
705     if (dispState == DisplayState::DISPLAY_OFF) {
706         SetState(PowerState::SLEEP, StateChangeReason::STATE_CHANGE_REASON_TIMEOUT);
707     } else {
708         POWER_HILOGW(FEATURE_ACTIVITY, "Display is on, ignore activity sleep timeout, state = %{public}d", dispState);
709     }
710 }
711 
HandleSystemWakeup()712 void PowerStateMachine::HandleSystemWakeup()
713 {
714     POWER_HILOGD(FEATURE_WAKEUP, "Enter, displayState = %{public}d", stateAction_->GetDisplayState());
715     if (IsScreenOn()) {
716         SetState(PowerState::AWAKE, StateChangeReason::STATE_CHANGE_REASON_SYSTEM, true);
717     } else {
718         SetState(PowerState::INACTIVE, StateChangeReason::STATE_CHANGE_REASON_SYSTEM, true);
719     }
720 }
721 
CheckRunningLock(PowerState state)722 bool PowerStateMachine::CheckRunningLock(PowerState state)
723 {
724     POWER_HILOGD(FEATURE_RUNNING_LOCK, "Enter, state = %{public}u", state);
725     auto pms = pms_.promote();
726     if (pms == nullptr) {
727         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Pms is nullptr");
728         return false;
729     }
730     auto runningLockMgr = pms->GetRunningLockMgr();
731     if (runningLockMgr == nullptr) {
732         POWER_HILOGE(FEATURE_RUNNING_LOCK, "RunningLockMgr is nullptr");
733         return false;
734     }
735     auto iterator = lockMap_.find(state);
736     if (iterator == lockMap_.end()) {
737         POWER_HILOGI(FEATURE_RUNNING_LOCK, "No specific lock in lockMap_ for state: %{public}u", state);
738         return true;
739     }
740 
741     std::shared_ptr<std::vector<RunningLockType>> pLock = iterator->second;
742     for (std::vector<RunningLockType>::const_iterator iter = pLock->begin(); iter != pLock->end(); ++iter) {
743         uint32_t count = runningLockMgr->GetValidRunningLockNum(*iter);
744         if (count > 0) {
745             POWER_HILOGI(FEATURE_POWER_STATE,
746                 "RunningLock %{public}s is locking (count=%{public}d), blocking %{public}s",
747                 GetRunningLockTypeString(*iter).c_str(), count, GetPowerStateString(state).c_str());
748             return false;
749         }
750     }
751 
752     POWER_HILOGI(FEATURE_RUNNING_LOCK, "No specific lock for state: %{public}u", state);
753     return true;
754 }
755 
SetDisplayOffTime(int64_t time,bool needUpdateSetting)756 void PowerStateMachine::SetDisplayOffTime(int64_t time, bool needUpdateSetting)
757 {
758     POWER_HILOGI(FEATURE_POWER_STATE, "set display off time %{public}" PRId64 " -> %{public}" PRId64 "",
759         displayOffTime_.load(), time);
760     displayOffTime_ = time;
761     if (currentState_ == PowerState::AWAKE) {
762         ResetInactiveTimer();
763     }
764     if (needUpdateSetting) {
765         SettingHelper::SetSettingDisplayOffTime(displayOffTime_);
766     }
767 }
768 
DisplayOffTimeUpdateFunc()769 static void DisplayOffTimeUpdateFunc()
770 {
771     auto stateMachine = DelayedSpSingleton<PowerMgrService>::GetInstance()->GetPowerStateMachine();
772     int64_t systemTime = stateMachine->GetDisplayOffTime();
773     auto settingTime = SettingHelper::GetSettingDisplayOffTime(systemTime);
774     if (settingTime == systemTime) {
775         return;
776     }
777     POWER_HILOGD(FEATURE_POWER_STATE, "setting update display off time %{public}" PRId64 " -> %{public}" PRId64 "",
778         systemTime, settingTime);
779     stateMachine->SetDisplayOffTime(settingTime, false);
780 }
781 
RegisterDisplayOffTimeObserver()782 void PowerStateMachine::RegisterDisplayOffTimeObserver()
783 {
784     if (g_displayOffTimeObserver) {
785         POWER_HILOGI(FEATURE_POWER_STATE, "setting display off time observer is already registered");
786         return;
787     }
788     DisplayOffTimeUpdateFunc();
789     SettingObserver::UpdateFunc updateFunc = [&](const std::string&) {
790         DisplayOffTimeUpdateFunc();
791     };
792     g_displayOffTimeObserver = SettingHelper::RegisterSettingDisplayOffTimeObserver(updateFunc);
793 }
794 
UnregisterDisplayOffTimeObserver()795 void PowerStateMachine::UnregisterDisplayOffTimeObserver()
796 {
797     if (g_displayOffTimeObserver == nullptr) {
798         POWER_HILOGD(FEATURE_POWER_STATE, "g_displayOffTimeObserver is nullptr, no need to unregister");
799         return;
800     }
801     SettingHelper::UnregisterSettingDisplayOffTimeObserver(g_displayOffTimeObserver);
802     g_displayOffTimeObserver = nullptr;
803 }
804 
SetSleepTime(int64_t time)805 void PowerStateMachine::SetSleepTime(int64_t time)
806 {
807     sleepTime_ = time;
808 }
809 
GetDisplayOffTime()810 int64_t PowerStateMachine::GetDisplayOffTime()
811 {
812     return displayOffTime_;
813 }
814 
GetSleepTime()815 int64_t PowerStateMachine::GetSleepTime()
816 {
817     return sleepTime_;
818 }
819 
SetState(PowerState state,StateChangeReason reason,bool force)820 bool PowerStateMachine::SetState(PowerState state, StateChangeReason reason, bool force)
821 {
822     POWER_HILOGD(FEATURE_POWER_STATE, "state=%{public}d, reason=%{public}d, force=%{public}d", state, reason, force);
823     auto iterator = controllerMap_.find(state);
824     if (iterator == controllerMap_.end()) {
825         return false;
826     }
827     std::shared_ptr<StateController> pController = iterator->second;
828     if (pController == nullptr) {
829         POWER_HILOGW(FEATURE_POWER_STATE, "StateController is not init");
830         return false;
831     }
832     TransitResult ret = pController->TransitTo(reason, true);
833     POWER_HILOGI(FEATURE_POWER_STATE, "StateController::TransitTo ret: %{public}d", ret);
834     return (ret == TransitResult::SUCCESS || ret == TransitResult::ALREADY_IN_STATE);
835 }
836 
SetDisplaySuspend(bool enable)837 void PowerStateMachine::SetDisplaySuspend(bool enable)
838 {
839     POWER_HILOGD(FEATURE_POWER_STATE, "enable: %{public}d", enable);
840     enableDisplaySuspend_ = enable;
841     if (GetState() == PowerState::INACTIVE) {
842         POWER_HILOGI(FEATURE_POWER_STATE, "Change display state");
843         if (enable) {
844             stateAction_->SetDisplayState(
845                 DisplayState::DISPLAY_SUSPEND, StateChangeReason::STATE_CHANGE_REASON_APPLICATION);
846         } else {
847             stateAction_->SetDisplayState(
848                 DisplayState::DISPLAY_OFF, StateChangeReason::STATE_CHANGE_REASON_APPLICATION);
849         }
850     }
851 }
852 
GetReasonByUserActivity(UserActivityType type)853 StateChangeReason PowerStateMachine::GetReasonByUserActivity(UserActivityType type)
854 {
855     StateChangeReason ret = StateChangeReason::STATE_CHANGE_REASON_UNKNOWN;
856     switch (type) {
857         case UserActivityType::USER_ACTIVITY_TYPE_BUTTON:
858             ret = StateChangeReason::STATE_CHANGE_REASON_HARD_KEY;
859             break;
860         case UserActivityType::USER_ACTIVITY_TYPE_TOUCH:
861             ret = StateChangeReason::STATE_CHANGE_REASON_TOUCH;
862             break;
863         case UserActivityType::USER_ACTIVITY_TYPE_ACCESSIBILITY:
864             ret = StateChangeReason::STATE_CHANGE_REASON_ACCESSIBILITY;
865             break;
866         case UserActivityType::USER_ACTIVITY_TYPE_SOFTWARE:
867             ret = StateChangeReason::STATE_CHANGE_REASON_APPLICATION;
868             break;
869         case UserActivityType::USER_ACTIVITY_TYPE_ATTENTION: // fail through
870         case UserActivityType::USER_ACTIVITY_TYPE_OTHER:     // fail through
871         default:
872             break;
873     }
874     return ret;
875 }
876 
GetReasonByWakeType(WakeupDeviceType type)877 StateChangeReason PowerStateMachine::GetReasonByWakeType(WakeupDeviceType type)
878 {
879     POWER_HILOGD(FEATURE_WAKEUP, "WakeupDeviceType :%{public}u", type);
880     StateChangeReason ret = StateChangeReason::STATE_CHANGE_REASON_UNKNOWN;
881     switch (type) {
882         case WakeupDeviceType::WAKEUP_DEVICE_POWER_BUTTON:
883             ret = StateChangeReason::STATE_CHANGE_REASON_POWER_KEY;
884             break;
885         case WakeupDeviceType::WAKEUP_DEVICE_WAKE_KEY:
886             ret = StateChangeReason::STATE_CHANGE_REASON_HARD_KEY;
887             break;
888         case WakeupDeviceType::WAKEUP_DEVICE_APPLICATION:
889             ret = StateChangeReason::STATE_CHANGE_REASON_APPLICATION;
890             break;
891         case WakeupDeviceType::WAKEUP_DEVICE_PLUGGED_IN: // fall through
892         case WakeupDeviceType::WAKEUP_DEVICE_HDMI:
893             ret = StateChangeReason::STATE_CHANGE_REASON_CABLE;
894             break;
895         case WakeupDeviceType::WAKEUP_DEVICE_GESTURE:
896             ret = StateChangeReason::STATE_CHANGE_REASON_TOUCH;
897             break;
898         case WakeupDeviceType::WAKEUP_DEVICE_CAMERA_LAUNCH:
899             ret = StateChangeReason::STATE_CHANGE_REASON_CAMERA;
900             break;
901         case WakeupDeviceType::WAKEUP_DEVICE_WAKE_MOTION:
902             ret = StateChangeReason::STATE_CHANGE_REASON_SENSOR;
903             break;
904         case WakeupDeviceType::WAKEUP_DEVICE_LID:
905             ret = StateChangeReason::STATE_CHANGE_REASON_LID;
906             break;
907         case WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK:
908             ret = StateChangeReason::STATE_CHANGE_REASON_DOUBLE_CLICK;
909             break;
910         case WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD:
911             ret = StateChangeReason::STATE_CHANGE_REASON_KEYBOARD;
912             break;
913         case WakeupDeviceType::WAKEUP_DEVICE_MOUSE:
914             ret = StateChangeReason::STATE_CHANGE_REASON_MOUSE;
915             break;
916         case WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN: // fail through
917         default:
918             break;
919     }
920     POWER_HILOGD(FEATURE_WAKEUP, "StateChangeReason: %{public}u", ret);
921     return ret;
922 }
923 
GetReasionBySuspendType(SuspendDeviceType type)924 StateChangeReason PowerStateMachine::GetReasionBySuspendType(SuspendDeviceType type)
925 {
926     POWER_HILOGD(FEATURE_SUSPEND, "SuspendDeviceType: %{public}u", type);
927     StateChangeReason ret = StateChangeReason::STATE_CHANGE_REASON_UNKNOWN;
928     switch (type) {
929         case SuspendDeviceType::SUSPEND_DEVICE_REASON_APPLICATION:
930             ret = StateChangeReason::STATE_CHANGE_REASON_APPLICATION;
931             break;
932         case SuspendDeviceType::SUSPEND_DEVICE_REASON_DEVICE_ADMIN:
933             ret = StateChangeReason::STATE_CHANGE_REASON_REMOTE;
934             break;
935         case SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT:
936             ret = StateChangeReason::STATE_CHANGE_REASON_TIMEOUT;
937             break;
938         case SuspendDeviceType::SUSPEND_DEVICE_REASON_LID:
939             ret = StateChangeReason::STATE_CHANGE_REASON_LID;
940             break;
941         case SuspendDeviceType::SUSPEND_DEVICE_REASON_POWER_KEY: // fall through
942         case SuspendDeviceType::SUSPEND_DEVICE_REASON_SLEEP_KEY:
943             ret = StateChangeReason::STATE_CHANGE_REASON_HARD_KEY;
944             break;
945         case SuspendDeviceType::SUSPEND_DEVICE_REASON_HDMI:
946             ret = StateChangeReason::STATE_CHANGE_REASON_CABLE;
947             break;
948         case SuspendDeviceType::SUSPEND_DEVICE_REASON_ACCESSIBILITY:
949             ret = StateChangeReason::STATE_CHANGE_REASON_ACCESSIBILITY;
950             break;
951         case SuspendDeviceType::SUSPEND_DEVICE_REASON_FORCE_SUSPEND:
952             ret = StateChangeReason::STATE_CHANGE_REASON_SYSTEM;
953             break;
954         default:
955             break;
956     }
957     POWER_HILOGD(FEATURE_SUSPEND, "StateChangeReason: %{public}u", ret);
958     return ret;
959 }
960 
AppendDumpInfo(std::string & result,std::string & reason,std::string & time)961 void PowerStateMachine::AppendDumpInfo(std::string& result, std::string& reason, std::string& time)
962 {
963     result.append("POWER STATE DUMP:\n");
964     result.append("Current State: ")
965         .append(GetPowerStateString(GetState()))
966         .append("  Reason: ")
967         .append(reason)
968         .append("  Time: ")
969         .append(time)
970         .append("\n");
971 
972     result.append("ScreenOffTime: Timeout=");
973     if (isScreenOffTimeOverride_) {
974         result.append((ToString(beforeOverrideTime_)))
975             .append("ms  OverrideTimeout=")
976             .append((ToString(GetDisplayOffTime())))
977             .append("ms\n");
978     } else {
979         result.append((ToString(GetDisplayOffTime()))).append("ms\n");
980     }
981 
982     result.append("DUMP DETAILS:\n");
983     result.append("Last Screen On: ").append(ToString(mDeviceState_.screenState.lastOnTime)).append("\n");
984     result.append("Last Screen Off: ").append(ToString(mDeviceState_.screenState.lastOffTime)).append("\n");
985     result.append("Last SuspendDevice: ").append(ToString(mDeviceState_.lastSuspendDeviceTime)).append("\n");
986     result.append("Last WakeupDevice: ").append(ToString(mDeviceState_.lastWakeupDeviceTime)).append("\n");
987     result.append("Last Refresh: ").append(ToString(mDeviceState_.lastRefreshActivityTime)).append("\n");
988 
989     result.append("DUMP EACH STATES:\n");
990     for (auto it = controllerMap_.begin(); it != controllerMap_.end(); it++) {
991         result.append("State: ")
992             .append(GetPowerStateString(it->second->GetState()))
993             .append("   Reason: ")
994             .append(GetReasonTypeString(it->second->lastReason_).c_str())
995             .append("   Time: ")
996             .append(ToString(it->second->lastTime_))
997             .append("\n")
998             .append("   Failure: ")
999             .append(GetReasonTypeString(it->second->failTrigger_).c_str())
1000             .append("   Reason: ")
1001             .append(it->second->failReasion_)
1002             .append("   From: ")
1003             .append(GetPowerStateString(it->second->failFrom_))
1004             .append("   Time: ")
1005             .append(ToString(it->second->failTime_))
1006             .append("\n\n");
1007     }
1008 }
1009 
DumpInfo(std::string & result)1010 void PowerStateMachine::DumpInfo(std::string& result)
1011 {
1012     std::string reason = "UNKNOWN";
1013     std::string time = "UNKNOWN";
1014     auto it = controllerMap_.find(GetState());
1015     if (it != controllerMap_.end() && it->second != nullptr) {
1016         reason = ToString(static_cast<uint32_t>(it->second->lastReason_));
1017         time = ToString(it->second->lastTime_);
1018     }
1019     AppendDumpInfo(result, reason, time);
1020 }
1021 
TransitTo(StateChangeReason reason,bool ignoreLock)1022 TransitResult PowerStateMachine::StateController::TransitTo(StateChangeReason reason, bool ignoreLock)
1023 {
1024     POWER_HILOGD(FEATURE_POWER_STATE, "Start");
1025     std::shared_ptr<PowerStateMachine> owner = owner_.lock();
1026     if (owner == nullptr) {
1027         POWER_HILOGW(FEATURE_POWER_STATE, "owner is nullptr");
1028         return TransitResult::OTHER_ERR;
1029     }
1030     POWER_HILOGI(FEATURE_POWER_STATE, "Transit from %{public}s to %{public}s for %{public}s ignoreLock=%{public}d",
1031         GetPowerStateString(owner->currentState_).c_str(), GetPowerStateString(this->state_).c_str(),
1032         GetReasonTypeString(reason).c_str(), ignoreLock);
1033     MatchState(owner->currentState_, owner->stateAction_->GetDisplayState());
1034     if (!CheckState()) {
1035         POWER_HILOGD(FEATURE_POWER_STATE, "Already in state: %{public}d", owner->currentState_);
1036         RecordFailure(owner->currentState_, reason, TransitResult::ALREADY_IN_STATE);
1037         return TransitResult::ALREADY_IN_STATE;
1038     }
1039     if (!ignoreLock && !owner->CheckRunningLock(GetState())) {
1040         POWER_HILOGD(FEATURE_POWER_STATE, "Running lock block");
1041         RecordFailure(owner->currentState_, reason, TransitResult::LOCKING);
1042         return TransitResult::LOCKING;
1043     }
1044     TransitResult ret = action_(reason);
1045     if (ret == TransitResult::SUCCESS) {
1046         lastReason_ = reason;
1047         lastTime_ = GetTickCount();
1048         owner->currentState_ = GetState();
1049         owner->NotifyPowerStateChanged(owner->currentState_);
1050     } else {
1051         RecordFailure(owner->currentState_, reason, ret);
1052     }
1053 
1054     POWER_HILOGD(FEATURE_POWER_STATE, "Finish, result: %{public}d", ret);
1055     return ret;
1056 }
1057 
CheckState()1058 bool PowerStateMachine::StateController::CheckState()
1059 {
1060     std::shared_ptr<PowerStateMachine> owner = owner_.lock();
1061     if (owner == nullptr) {
1062         POWER_HILOGW(FEATURE_POWER_STATE, "Owner is nullptr");
1063         return false;
1064     }
1065     auto state = GetState();
1066     POWER_HILOGD(FEATURE_POWER_STATE, "state: %{public}u, currentState_: %{public}u", state, owner->currentState_);
1067     return state != owner->currentState_;
1068 }
1069 
CorrectState(PowerState & currentState,PowerState correctState,DisplayState state)1070 void PowerStateMachine::StateController::CorrectState(
1071     PowerState& currentState, PowerState correctState, DisplayState state)
1072 {
1073     std::string msg = "Correct power state errors from";
1074     msg.append(GetPowerStateString(currentState))
1075         .append(" to ")
1076         .append(GetPowerStateString(correctState))
1077         .append(" due to cuurent display state is ")
1078         .append(GetDisplayStateString(state));
1079     POWER_HILOGW(FEATURE_POWER_STATE, "%{public}s", msg.c_str());
1080     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "STATE_CORRECTION", HiviewDFX::HiSysEvent::EventType::FAULT,
1081         "ERROR_STATE", static_cast<uint32_t>(currentState), "CORRECTION_STATE", static_cast<uint32_t>(correctState),
1082         "DISPLAY_STATE", static_cast<uint32_t>(state), "MSG", msg);
1083     currentState = correctState;
1084 }
1085 
MatchState(PowerState & currentState,DisplayState state)1086 void PowerStateMachine::StateController::MatchState(PowerState& currentState, DisplayState state)
1087 {
1088     if (GetState() == PowerState::SLEEP || currentState == PowerState::SLEEP || GetState() == PowerState::HIBERNATE ||
1089         currentState == PowerState::HIBERNATE || GetState() == PowerState::SHUTDOWN ||
1090         currentState == PowerState::SHUTDOWN) {
1091         return;
1092     }
1093 
1094     // Keep the state of display consistent with the state of power
1095     switch (state) {
1096         case DisplayState::DISPLAY_OFF:
1097             if (currentState == PowerState::AWAKE || currentState == PowerState::FREEZE) {
1098                 CorrectState(currentState, PowerState::INACTIVE, state);
1099             }
1100             break;
1101         case DisplayState::DISPLAY_DIM:
1102         case DisplayState::DISPLAY_ON:
1103             if (currentState == PowerState::INACTIVE || currentState == PowerState::STAND_BY ||
1104                 currentState == PowerState::DOZE) {
1105                 CorrectState(currentState, PowerState::AWAKE, state);
1106             }
1107             break;
1108         case DisplayState::DISPLAY_SUSPEND:
1109         case DisplayState::DISPLAY_UNKNOWN:
1110         default:
1111             break;
1112     }
1113 }
1114 
RecordFailure(PowerState from,StateChangeReason trigger,TransitResult failReason)1115 void PowerStateMachine::StateController::RecordFailure(
1116     PowerState from, StateChangeReason trigger, TransitResult failReason)
1117 {
1118     failFrom_ = from;
1119     failTrigger_ = trigger;
1120     failTime_ = GetTickCount();
1121     switch (failReason) {
1122         case TransitResult::ALREADY_IN_STATE:
1123             failReasion_ = "Already in the state";
1124             break;
1125         case TransitResult::LOCKING:
1126             failReasion_ = "Blocked by running lock";
1127             break;
1128         case TransitResult::HDI_ERR:
1129             failReasion_ = "Power HDI error";
1130             break;
1131         case TransitResult::DISPLAY_ON_ERR:
1132             failReasion_ = "SetDisplayState(ON) error";
1133             break;
1134         case TransitResult::DISPLAY_OFF_ERR:
1135             failReasion_ = "SetDisplayState(OFF) error";
1136             break;
1137         case TransitResult::OTHER_ERR:
1138         default:
1139             failReasion_ = "Unknown Error";
1140             break;
1141     }
1142     std::string message = "State Transit Failed from ";
1143     message.append(GetPowerStateString(failFrom_))
1144         .append(" to ")
1145         .append(GetPowerStateString(GetState()))
1146         .append(" by ")
1147         .append(GetReasonTypeString(failTrigger_).c_str())
1148         .append("   Reason:")
1149         .append(failReasion_)
1150         .append("   Time:")
1151         .append(ToString(failTime_))
1152         .append("\n");
1153     const int logLevel = 2;
1154     const std::string tag = "TAG_POWER";
1155     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "SCREEN", HiviewDFX::HiSysEvent::EventType::FAULT,
1156         "LOG_LEVEL", logLevel, "TAG", tag, "MESSAGE", message);
1157     POWER_HILOGI(FEATURE_POWER_STATE, "RecordFailure: %{public}s", message.c_str());
1158 }
1159 } // namespace PowerMgr
1160 } // namespace OHOS
1161