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