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