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