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