1 /*
2  * Copyright (c) 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 "suspend_controller.h"
17 #include <datetime_ex.h>
18 #ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
19 #include <display_manager_lite.h>
20 #endif
21 #ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
22 #include <hisysevent.h>
23 #endif
24 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
25 #include <input_manager.h>
26 #endif
27 #include <ipc_skeleton.h>
28 #include <securec.h>
29 #ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
30 #include <screen_manager_lite.h>
31 #endif
32 #include "power_log.h"
33 #include "power_mgr_service.h"
34 #include "power_state_callback_stub.h"
35 #include "setting_helper.h"
36 #include "system_suspend_controller.h"
37 #include "wakeup_controller.h"
38 
39 namespace OHOS {
40 namespace PowerMgr {
41 using namespace OHOS::MMI;
42 namespace {
43 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
44 sptr<SettingObserver> g_suspendSourcesKeyAcObserver = nullptr;
45 sptr<SettingObserver> g_suspendSourcesKeyDcObserver = nullptr;
46 #else
47 sptr<SettingObserver> g_suspendSourcesKeyObserver = nullptr;
48 #endif
49 FFRTMutex g_monitorMutex;
50 constexpr int64_t POWERKEY_MIN_INTERVAL = 350; // ms
51 } // namespace
52 
53 std::atomic_bool onForceSleep = false;
54 
55 /** SuspendController Implement */
SuspendController(const std::shared_ptr<ShutdownController>& shutdownController, const std::shared_ptr<PowerStateMachine>& stateMachine, const std::shared_ptr<FFRTTimer>& ffrtTimer)56 SuspendController::SuspendController(const std::shared_ptr<ShutdownController>& shutdownController,
57     const std::shared_ptr<PowerStateMachine>& stateMachine, const std::shared_ptr<FFRTTimer>& ffrtTimer)
58 {
59     shutdownController_ = shutdownController;
60     stateMachine_ = stateMachine;
61     ffrtTimer_ = ffrtTimer;
62 }
63 
~SuspendController()64 SuspendController::~SuspendController()
65 {
66     UnregisterSettingsObserver();
67     ffrtTimer_.reset();
68 }
69 
AddCallback(const sptr<ISyncSleepCallback>& callback, SleepPriority priority)70 void SuspendController::AddCallback(const sptr<ISyncSleepCallback>& callback, SleepPriority priority)
71 {
72     RETURN_IF(callback == nullptr)
73     SleepCallbackHolder::GetInstance().AddCallback(callback, priority);
74     POWER_HILOGI(FEATURE_SUSPEND,
75         "sync sleep callback added, priority=%{public}u, pid=%{public}d, uid=%{public}d", priority,
76         IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
77 }
78 
RemoveCallback(const sptr<ISyncSleepCallback>& callback)79 void SuspendController::RemoveCallback(const sptr<ISyncSleepCallback>& callback)
80 {
81     RETURN_IF(callback == nullptr)
82     SleepCallbackHolder::GetInstance().RemoveCallback(callback);
83     POWER_HILOGI(FEATURE_SUSPEND,
84         "sync sleep callback removed, pid=%{public}d, uid=%{public}d",
85         IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
86 }
87 
TriggerSyncSleepCallback(bool isWakeup)88 void SuspendController::TriggerSyncSleepCallback(bool isWakeup)
89 {
90     POWER_HILOGI(FEATURE_SUSPEND,
91         "TriggerSyncSleepCallback, isWakeup=%{public}d, onForceSleep=%{public}d",
92         isWakeup, onForceSleep == true);
93     auto highPriorityCallbacks = SleepCallbackHolder::GetInstance().GetHighPriorityCallbacks();
94     TriggerSyncSleepCallbackInner(highPriorityCallbacks, "High", isWakeup);
95     auto defaultPriorityCallbacks = SleepCallbackHolder::GetInstance().GetDefaultPriorityCallbacks();
96     TriggerSyncSleepCallbackInner(defaultPriorityCallbacks, "Default", isWakeup);
97     auto lowPriorityCallbacks = SleepCallbackHolder::GetInstance().GetLowPriorityCallbacks();
98     TriggerSyncSleepCallbackInner(lowPriorityCallbacks, "Low", isWakeup);
99 
100     if (isWakeup && onForceSleep) {
101         onForceSleep = false;
102     }
103 }
104 
TriggerSyncSleepCallbackInner(std::set<sptr<ISyncSleepCallback>>& callbacks, const std::string& priority, bool isWakeup)105 void SuspendController::TriggerSyncSleepCallbackInner(std::set<sptr<ISyncSleepCallback>>& callbacks,
106     const std::string& priority, bool isWakeup)
107 {
108     uint32_t id = 0;
109     for (auto &callback : callbacks) {
110         if (callback != nullptr) {
111             int64_t start = GetTickCount();
112             isWakeup ? callback->OnSyncWakeup(onForceSleep) : callback->OnSyncSleep(onForceSleep);
113             int64_t cost = GetTickCount() - start;
114             POWER_HILOGI(FEATURE_SUSPEND,
115                 "Trigger %{public}s SyncSleepCallback[%{public}u] success, cost=%{public}" PRId64,
116                 priority.c_str(), ++id, cost);
117         }
118     }
119 }
120 
121 class SuspendPowerStateCallback : public PowerStateCallbackStub {
122 public:
SuspendPowerStateCallback(std::shared_ptr<SuspendController> controller)123     explicit SuspendPowerStateCallback(std::shared_ptr<SuspendController> controller) : controller_(controller) {};
124     virtual ~SuspendPowerStateCallback() = default;
125     void OnPowerStateChanged(PowerState state) override
126     {
127         auto controller = controller_.lock();
128         if (controller == nullptr) {
129             POWER_HILOGI(FEATURE_SUSPEND, "OnPowerStateChanged: No controller");
130             return;
131         }
132         if (state == PowerState::AWAKE) {
133             POWER_HILOGI(FEATURE_SUSPEND, "Turn awake, stop sleep timer");
134             controller->StopSleep();
135         }
136     }
137 
138 private:
139     std::weak_ptr<SuspendController> controller_;
140 };
141 
Init()142 void SuspendController::Init()
143 {
144     std::lock_guard lock(mutex_);
145     std::shared_ptr<SuspendSources> sources = SuspendSourceParser::ParseSources();
146     sourceList_ = sources->GetSourceList();
147     if (sourceList_.empty()) {
148         POWER_HILOGE(FEATURE_SUSPEND, "InputManager is null");
149         return;
150     }
151 
152     for (auto source = sourceList_.begin(); source != sourceList_.end(); source++) {
153         POWER_HILOGI(FEATURE_SUSPEND, "registered type=%{public}u action=%{public}u delayMs=%{public}u",
154             (*source).GetReason(), (*source).GetAction(), (*source).GetDelay());
155         std::shared_ptr<SuspendMonitor> monitor = SuspendMonitor::CreateMonitor(*source);
156         if (monitor != nullptr && monitor->Init()) {
157             POWER_HILOGI(FEATURE_SUSPEND, "monitor init success, type=%{public}u", (*source).GetReason());
158             monitor->RegisterListener([this](SuspendDeviceType reason, uint32_t action, uint32_t delay) {
159                 this->ControlListener(reason, action, delay);
160             });
161             g_monitorMutex.lock();
162             monitorMap_.emplace(monitor->GetReason(), monitor);
163             g_monitorMutex.unlock();
164         }
165     }
166     sptr<SuspendPowerStateCallback> callback = new SuspendPowerStateCallback(shared_from_this());
167     if (stateMachine_ == nullptr) {
168         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
169         return;
170     }
171     stateMachine_->RegisterPowerStateCallback(callback);
172     RegisterSettingsObserver();
173 }
174 
ExecSuspendMonitorByReason(SuspendDeviceType reason)175 void SuspendController::ExecSuspendMonitorByReason(SuspendDeviceType reason)
176 {
177     FFRTUtils::SubmitTask([this, reason] {
178         g_monitorMutex.lock();
179         auto suspendMonitor = GetSpecifiedSuspendMonitor(reason);
180         if (suspendMonitor == nullptr) {
181             POWER_HILOGI(COMP_SVC, "get monitor fail, type: %{public}u", reason);
182             g_monitorMutex.unlock();
183             return;
184         }
185         suspendMonitor->Notify();
186         g_monitorMutex.unlock();
187     });
188 }
189 
UpdateSuspendSources()190 void SuspendController::UpdateSuspendSources()
191 {
192     POWER_HILOGI(COMP_SVC, "start setting string update");
193     std::lock_guard lock(mutex_);
194 
195     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
196     if (pms == nullptr) {
197         POWER_HILOGE(COMP_SVC, "get PowerMgrService fail");
198         return;
199     }
200     std::string jsonStr;
201 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
202     if (pms->IsPowerConnected()) {
203         jsonStr = SettingHelper::GetSettingAcSuspendSources();
204     } else {
205         jsonStr = SettingHelper::GetSettingDcSuspendSources();
206     }
207 #else
208     jsonStr = SettingHelper::GetSettingSuspendSources();
209 #endif
210     std::shared_ptr<SuspendSources> sources = SuspendSourceParser::ParseSources(jsonStr);
211     std::vector<SuspendSource> updateSourceList = sources->GetSourceList();
212     if (updateSourceList.size() == 0) {
213         return;
214     }
215     sourceList_ = updateSourceList;
216     POWER_HILOGI(COMP_SVC, "start updateListener");
217     Cancel();
218     uint32_t id = 0;
219     for (auto source = sourceList_.begin(); source != sourceList_.end(); source++, id++) {
220         std::shared_ptr<SuspendMonitor> monitor = SuspendMonitor::CreateMonitor(*source);
221         POWER_HILOGI(FEATURE_SUSPEND, "UpdateFunc CreateMonitor[%{public}u] reason=%{public}d",
222             id, source->GetReason());
223         if (monitor != nullptr && monitor->Init()) {
224             monitor->RegisterListener([this](SuspendDeviceType reason, uint32_t action, uint32_t delay) {
225                 this->ControlListener(reason, action, delay);
226             });
227             g_monitorMutex.lock();
228             monitorMap_.emplace(monitor->GetReason(), monitor);
229             g_monitorMutex.unlock();
230         }
231     }
232 }
233 
RegisterSettingsObserver()234 void SuspendController::RegisterSettingsObserver()
235 {
236 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
237     if (g_suspendSourcesKeyAcObserver && g_suspendSourcesKeyDcObserver) {
238 #else
239     if (g_suspendSourcesKeyObserver) {
240 #endif
241         POWER_HILOGE(FEATURE_POWER_STATE, "suspend sources key observer is already registered");
242         return;
243     }
244     SettingObserver::UpdateFunc updateFunc = [&](const std::string&) {
245         SuspendController::UpdateSuspendSources();
246     };
247 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
248     if (g_suspendSourcesKeyAcObserver == nullptr) {
249         g_suspendSourcesKeyAcObserver = SettingHelper::RegisterSettingAcSuspendSourcesObserver(updateFunc);
250     }
251     if (g_suspendSourcesKeyDcObserver == nullptr) {
252         g_suspendSourcesKeyDcObserver = SettingHelper::RegisterSettingDcSuspendSourcesObserver(updateFunc);
253     }
254 #else
255     g_suspendSourcesKeyObserver = SettingHelper::RegisterSettingSuspendSourcesObserver(updateFunc);
256 #endif
257     POWER_HILOGI(FEATURE_POWER_STATE, "register setting observer fin");
258 }
259 
260 void SuspendController::UnregisterSettingsObserver()
261 {
262 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
263     if (g_suspendSourcesKeyAcObserver) {
264         SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyAcObserver);
265         g_suspendSourcesKeyAcObserver = nullptr;
266     }
267     if (g_suspendSourcesKeyDcObserver) {
268         SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyDcObserver);
269         g_suspendSourcesKeyDcObserver = nullptr;
270     }
271 #else
272     if (g_suspendSourcesKeyObserver) {
273         SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyObserver);
274         g_suspendSourcesKeyObserver = nullptr;
275     }
276 #endif
277 }
278 
279 void SuspendController::Execute()
280 {
281     HandleAction(GetLastReason(), GetLastAction());
282 }
283 
284 void SuspendController::Cancel()
285 {
286     g_monitorMutex.lock();
287     for (auto monitor = monitorMap_.begin(); monitor != monitorMap_.end(); monitor++) {
288         monitor->second->Cancel();
289     }
290     monitorMap_.clear();
291     g_monitorMutex.unlock();
292 }
293 
294 void SuspendController::StopSleep()
295 {
296     ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
297     if (ffrtTimer_ != nullptr) {
298         ffrtTimer_->CancelTimer(TIMER_ID_SLEEP);
299     }
300     sleepTime_ = -1;
301     sleepAction_ = static_cast<uint32_t>(SuspendAction::ACTION_NONE);
302     ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
303 }
304 
305 void SuspendController::HandleEvent(int64_t delayTime)
306 {
307     FFRTTask task = [&]() {
308         g_monitorMutex.lock();
309         auto timeoutSuspendMonitor = GetSpecifiedSuspendMonitor(SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT);
310         if (timeoutSuspendMonitor == nullptr) {
311             g_monitorMutex.unlock();
312             return;
313         }
314 
315         auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
316         if (pms != nullptr) {
317             if (pms->CheckDialogFlag()) {
318                 POWER_HILOGI(FEATURE_SUSPEND, "Reset long press flag before suspending device by timeout");
319             }
320         }
321         if (stateMachine_ != nullptr) {
322             int32_t timeout = stateMachine_->GetDisplayOffTime();
323             POWER_HILOGI(FEATURE_INPUT, "This time of timeout is %{public}d ms", timeout);
324         }
325         g_monitorMutex.unlock();
326         timeoutSuspendMonitor->HandleEvent();
327     };
328     if (ffrtTimer_ != nullptr) {
329         ffrtTimer_->SetTimer(TIMER_ID_USER_ACTIVITY_OFF, task, delayTime);
330     } else {
331         POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}s) failed, timer is null", __func__,
332             std::to_string(delayTime).c_str());
333     }
334 }
335 
336 void SuspendController::CancelEvent()
337 {
338     if (ffrtTimer_ != nullptr) {
339         ffrtTimer_->CancelTimer(TIMER_ID_USER_ACTIVITY_OFF);
340     }
341 }
342 
343 void SuspendController::RecordPowerKeyDown(bool interrupting)
344 {
345     if (stateMachine_ == nullptr) {
346         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
347         return;
348     }
349     bool isScreenOn = stateMachine_->IsScreenOn();
350     POWER_HILOGI(FEATURE_SUSPEND, "Suspend record key down action isScreenOn=%{public}d", isScreenOn);
351     if (!isScreenOn) {
352         powerkeyDownWhenScreenOff_ = true;
353     } else {
354         if (interrupting) {
355             POWER_HILOGI(FEATURE_SUSPEND, "Suspend record key down after interrupting screen off");
356         }
357         powerkeyDownWhenScreenOff_ = interrupting;
358     }
359 
360     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
361     if (pms == nullptr) {
362         return;
363     }
364 
365     if (pms->CheckDialogFlag()) {
366         return;
367     }
368 }
369 
370 bool SuspendController::GetPowerkeyDownWhenScreenOff()
371 {
372     bool powerKeyDown = powerkeyDownWhenScreenOff_;
373     powerkeyDownWhenScreenOff_ = false;
374     return powerKeyDown;
375 }
376 
377 void SuspendController::SuspendWhenScreenOff(SuspendDeviceType reason, uint32_t action, uint32_t delay)
378 {
379     if (reason != SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH) {
380         POWER_HILOGI(FEATURE_SUSPEND, "SuspendWhenScreenOff: Do nothing for reason %{public}u", reason);
381         return;
382     }
383     if (stateMachine_ == nullptr) {
384         return;
385     }
386 
387     POWER_HILOGI(FEATURE_SUSPEND,
388         "Suspend when screen off, reason=%{public}d, action=%{public}u, "
389         "delay=%{public}u, state=%{public}d, type=%{public}u",
390         reason, action, delay, stateMachine_->GetState(), sleepType_);
391     switch (stateMachine_->GetState()) {
392         case PowerState::INACTIVE:
393             StopSleep();
394             StartSleepTimer(reason, action, delay);
395             break;
396         case PowerState::SLEEP:
397             if (action != static_cast<uint32_t>(SuspendAction::ACTION_FORCE_SUSPEND)) {
398                 break;
399             }
400             if (sleepType_ == static_cast<uint32_t>(SuspendAction::ACTION_AUTO_SUSPEND)) {
401                 SystemSuspendController::GetInstance().Wakeup();
402                 StartSleepTimer(reason, action, 0);
403             } else if (sleepType_ == static_cast<uint32_t>(SuspendAction::ACTION_FORCE_SUSPEND)) {
404                 if (stateMachine_->IsSwitchOpen()) {
405                     POWER_HILOGI(FEATURE_SUSPEND, "switch off event is ignored.");
406                     return;
407                 }
408                 SystemSuspendController::GetInstance().Wakeup();
409                 SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, true);
410             } else {
411                 POWER_HILOGD(FEATURE_SUSPEND, "Nothing to do for no suspend");
412             }
413             break;
414         default:
415             break;
416     }
417 }
418 
419 void SuspendController::ControlListener(SuspendDeviceType reason, uint32_t action, uint32_t delay)
420 {
421     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
422     if (pms == nullptr) {
423         return;
424     }
425     if (stateMachine_ == nullptr) {
426         POWER_HILOGE(FEATURE_SUSPEND, "get PowerStateMachine instance error");
427         return;
428     }
429 
430     if (pms->CheckDialogAndShuttingDown()) {
431         return;
432     }
433 
434     bool isScreenOn = stateMachine_->IsScreenOn();
435     if (!isScreenOn) {
436         SuspendWhenScreenOff(reason, action, delay);
437         return;
438     }
439 
440 #ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
441     if (IsPowerOffInernalScreenOnlyScene(reason, static_cast<SuspendAction>(action), isScreenOn)) {
442         ProcessPowerOffInternalScreenOnly(pms, reason);
443         return;
444     }
445 #endif
446 
447     pid_t pid = IPCSkeleton::GetCallingPid();
448     auto uid = IPCSkeleton::GetCallingUid();
449     POWER_HILOGI(FEATURE_SUSPEND,
450         "[UL_POWER] Try to suspend device, pid=%{public}d, uid=%{public}d, reason=%{public}d, action=%{public}u, "
451         "delay=%{public}u",
452         pid, uid, reason, action, delay);
453     bool force = true;
454     if (reason == SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT) {
455         force = false;
456     }
457 #ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
458     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "SLEEP_START",
459         HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "TRIGGER_EVENT_TYPE", static_cast<int32_t>(reason),
460         "ACTION_EVENT_TYPE", static_cast<int32_t>(force));
461 #endif
462     bool ret = stateMachine_->SetState(
463         PowerState::INACTIVE, stateMachine_->GetReasonBySuspendType(static_cast<SuspendDeviceType>(reason)), force);
464     if (ret) {
465         StartSleepTimer(reason, action, delay);
466     }
467 }
468 
469 std::shared_ptr<SuspendMonitor> SuspendController::GetSpecifiedSuspendMonitor(SuspendDeviceType type) const
470 {
471     auto iter = monitorMap_.find(type);
472     if (iter == monitorMap_.end()) {
473         return nullptr;
474     }
475     return iter->second;
476 }
477 
478 #ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
479 void SuspendController::PowerOffInternalScreen(SuspendDeviceType type)
480 {
481     using namespace OHOS::Rosen;
482     uint64_t screenId = DisplayManagerLite::GetInstance().GetInternalScreenId();
483     bool ret = DisplayManagerLite::GetInstance().SetScreenPowerById(
484         screenId, ScreenPowerState::POWER_OFF, PowerStateChangeReason::STATE_CHANGE_REASON_SWITCH);
485     POWER_HILOGI(FEATURE_SUSPEND,
486         "Power off internal screen, type = %{public}u, screenId = %{public}u, ret = %{public}d", type,
487         static_cast<uint32_t>(screenId), ret);
488 }
489 
490 void SuspendController::PowerOffAllScreens(SuspendDeviceType type)
491 {
492     using namespace OHOS::Rosen;
493     bool ret = ScreenManagerLite::GetInstance().SetScreenPowerForAll(
494         ScreenPowerState::POWER_OFF, PowerStateChangeReason::STATE_CHANGE_REASON_SWITCH);
495     POWER_HILOGI(FEATURE_SUSPEND, "Power off all screens, type = %{public}u, ret = %{public}d", type, ret);
496 }
497 
498 bool SuspendController::IsPowerOffInernalScreenOnlyScene(
499     SuspendDeviceType reason, SuspendAction action, bool isScreenOn) const
500 {
501     if (reason == SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH && isScreenOn &&
502         action == SuspendAction::ACTION_NONE && stateMachine_->GetExternalScreenNumber() > 0) {
503         return true;
504     }
505     return false;
506 }
507 
508 void SuspendController::ProcessPowerOffInternalScreenOnly(const sptr<PowerMgrService>& pms, SuspendDeviceType reason)
509 {
510     POWER_HILOGI(
511         FEATURE_SUSPEND, "[UL_POWER] Power off internal screen when closing switch is configured as no operation");
512     PowerOffInternalScreen(reason);
513     pms->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_SWITCH, false);
514 }
515 #endif
516 
517 void SuspendController::StartSleepTimer(SuspendDeviceType reason, uint32_t action, uint32_t delay)
518 {
519     if (static_cast<SuspendAction>(action) == SuspendAction::ACTION_AUTO_SUSPEND) {
520         if (stateMachine_->GetSleepTime() < 0) {
521             POWER_HILOGI(FEATURE_SUSPEND, "sleeptime less than zero, no need suspend");
522             return;
523         }
524     }
525 
526     int64_t tick = GetTickCount();
527     int64_t timeout = tick + static_cast<int64_t>(delay);
528     if (timeout < tick) {
529         POWER_HILOGE(FEATURE_SUSPEND, "Sleep timer overflow with tick = %{public}s, delay = %{public}u",
530             std::to_string(tick).c_str(), delay);
531         return;
532     }
533 
534     ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
535     if ((timeout > sleepTime_) && (sleepTime_ != -1)) {
536         POWER_HILOGI(FEATURE_SUSPEND, "already have a sleep event (%{public}" PRId64 " > %{public}" PRId64 ")", timeout,
537             sleepTime_);
538         ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
539         return;
540     }
541     sleepTime_ = timeout;
542     sleepReason_ = reason;
543     sleepAction_ = action;
544     sleepDuration_ = delay;
545     sleepType_ = action;
546     FFRTTask task = [this, reason, action] {
547         HandleAction(reason, action);
548     };
549 
550     if (ffrtTimer_ != nullptr) {
551         ffrtTimer_->SetTimer(TIMER_ID_SLEEP, task, delay);
552     } else {
553         POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}u) failed, timer is null", __func__, delay);
554     }
555     ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
556 }
557 
558 void SuspendController::HandleAction(SuspendDeviceType reason, uint32_t action)
559 {
560     switch (static_cast<SuspendAction>(action)) {
561         case SuspendAction::ACTION_AUTO_SUSPEND:
562             HandleAutoSleep(reason);
563             break;
564         case SuspendAction::ACTION_FORCE_SUSPEND:
565             HandleForceSleep(reason);
566             break;
567         case SuspendAction::ACTION_HIBERNATE:
568             HandleHibernate(reason);
569             break;
570         case SuspendAction::ACTION_SHUTDOWN:
571             HandleShutdown(reason);
572             break;
573         case SuspendAction::ACTION_NONE:
574         default:
575             break;
576     }
577     ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
578     sleepTime_ = -1;
579     sleepAction_ = static_cast<uint32_t>(SuspendAction::ACTION_NONE);
580     ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
581 }
582 
583 void SuspendController::HandleAutoSleep(SuspendDeviceType reason)
584 {
585     POWER_HILOGI(FEATURE_SUSPEND, "auto suspend by reason=%{public}d", reason);
586 
587     if (stateMachine_ == nullptr) {
588         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
589         return;
590     }
591     bool ret = stateMachine_->SetState(
592         PowerState::SLEEP, stateMachine_->GetReasonBySuspendType(reason));
593     if (ret) {
594         POWER_HILOGI(FEATURE_SUSPEND, "State changed, set sleep timer");
595         TriggerSyncSleepCallback(false);
596         SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, false);
597     } else {
598         POWER_HILOGI(FEATURE_SUSPEND, "auto suspend: State change failed");
599     }
600 }
601 
602 void SuspendController::HandleForceSleep(SuspendDeviceType reason)
603 {
604     POWER_HILOGI(FEATURE_SUSPEND, "force suspend by reason=%{public}d", reason);
605     if (stateMachine_ == nullptr) {
606         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
607         return;
608     }
609 
610 #ifdef POWER_MANAGER_ENABLE_FORCE_SLEEP_BROADCAST
611     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
612     if (pms != nullptr && pms->GetSuspendController() != nullptr) {
613         pms->GetSuspendController()->SetForceSleepingFlag(true);
614         POWER_HILOGI(FEATURE_SUSPEND, "Set flag of force sleeping to true");
615     } else {
616         POWER_HILOGE(FEATURE_SUSPEND, "Failed to set flag of force sleeping, pms or suspendController is nullptr");
617     }
618 #endif
619     bool ret = stateMachine_->SetState(PowerState::SLEEP,
620         stateMachine_->GetReasonBySuspendType(reason), true);
621     if (ret) {
622         POWER_HILOGI(FEATURE_SUSPEND, "State changed, system suspend");
623         onForceSleep = true;
624         TriggerSyncSleepCallback(false);
625 
626         FFRTTask task = [this, reason] {
627             SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, true);
628         };
629         if (ffrtTimer_ != nullptr) {
630             ffrtTimer_->SetTimer(TIMER_ID_SLEEP, task, FORCE_SLEEP_DELAY_MS);
631         } else {
632             POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}d) failed, timer is null",
633                 __func__, FORCE_SLEEP_DELAY_MS);
634         }
635     } else {
636         POWER_HILOGI(FEATURE_SUSPEND, "force suspend: State change failed");
637     }
638 }
639 
640 void SuspendController::HandleHibernate(SuspendDeviceType reason)
641 {
642     POWER_HILOGI(FEATURE_SUSPEND, "force suspend by reason=%{public}d", reason);
643     if (stateMachine_ == nullptr) {
644         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
645         return;
646     }
647     bool ret = stateMachine_->SetState(
648         PowerState::HIBERNATE, stateMachine_->GetReasonBySuspendType(reason), true);
649     if (ret) {
650         POWER_HILOGI(FEATURE_SUSPEND, "State changed, call hibernate");
651     } else {
652         POWER_HILOGI(FEATURE_SUSPEND, "Hibernate: State change failed");
653     }
654 }
655 
656 void SuspendController::HandleShutdown(SuspendDeviceType reason)
657 {
658     POWER_HILOGI(FEATURE_SUSPEND, "shutdown by reason=%{public}d", reason);
659     shutdownController_->Shutdown(std::to_string(static_cast<uint32_t>(reason)));
660 }
661 
662 void SuspendController::Reset()
663 {
664     ffrtTimer_.reset();
665 }
666 
667 const std::shared_ptr<SuspendMonitor> SuspendMonitor::CreateMonitor(SuspendSource& source)
668 {
669     SuspendDeviceType reason = source.GetReason();
670     std::shared_ptr<SuspendMonitor> monitor = nullptr;
671     switch (reason) {
672         case SuspendDeviceType::SUSPEND_DEVICE_REASON_POWER_KEY:
673             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<PowerKeySuspendMonitor>(source));
674             break;
675         case SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT:
676             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<TimeoutSuspendMonitor>(source));
677             break;
678         case SuspendDeviceType::SUSPEND_DEVICE_REASON_LID:
679             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<LidSuspendMonitor>(source));
680             break;
681         case SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH:
682             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<SwitchSuspendMonitor>(source));
683             break;
684         default:
685             POWER_HILOGE(FEATURE_SUSPEND, "CreateMonitor : Invalid reason=%{public}d", reason);
686             break;
687     }
688     return monitor;
689 }
690 
691 /** PowerKeySuspendMonitor Implement */
692 bool PowerKeySuspendMonitor::Init()
693 {
694 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
695     if (powerkeyReleaseId_ >= 0) {
696         return true;
697     }
698     std::shared_ptr<OHOS::MMI::KeyOption> keyOption = std::make_shared<OHOS::MMI::KeyOption>();
699     std::set<int32_t> preKeys;
700 
701     keyOption.reset();
702     keyOption = std::make_shared<OHOS::MMI::KeyOption>();
703     keyOption->SetPreKeys(preKeys);
704     keyOption->SetFinalKey(OHOS::MMI::KeyEvent::KEYCODE_POWER);
705     keyOption->SetFinalKeyDown(false);
706     keyOption->SetFinalKeyDownDuration(0);
707     powerkeyReleaseId_ = InputManager::GetInstance()->SubscribeKeyEvent(
708         keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) {
709             POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER] Received powerkey up");
710 
711             static int64_t lastPowerkeyUpTime = 0;
712             int64_t currTime = GetTickCount();
713             if (lastPowerkeyUpTime != 0 && currTime - lastPowerkeyUpTime < POWERKEY_MIN_INTERVAL) {
714                 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Last powerkey up within 350ms, skip. "
715                     "%{public}" PRId64 ", %{public}" PRId64, currTime, lastPowerkeyUpTime);
716                 return;
717             }
718             lastPowerkeyUpTime = currTime;
719 
720             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
721             if (pms == nullptr) {
722                 return;
723             }
724             std::shared_ptr<SuspendController> suspendController = pms->GetSuspendController();
725             if (suspendController->GetPowerkeyDownWhenScreenOff()) {
726                 POWER_HILOGI(FEATURE_SUSPEND,
727                     "[UL_POWER] The powerkey was pressed when screenoff, ignore this powerkey up event.");
728                 return;
729             }
730             auto powerkeyScreenOffTask = [*this]() mutable {
731                 Notify();
732                 powerkeyScreenOff_ = false;
733                 EndPowerkeyScreenOff();
734             };
735             BeginPowerkeyScreenOff();
736             powerkeyScreenOff_ = true;
737             ffrt::submit(powerkeyScreenOffTask, {}, {&powerkeyScreenOff_});
738             POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER]submitted screen off ffrt task");
739         });
740     POWER_HILOGI(FEATURE_SUSPEND, "powerkeyReleaseId_=%{public}d", powerkeyReleaseId_);
741     return powerkeyReleaseId_ >= 0 ? true : false;
742 #else
743     return false;
744 #endif
745 }
746 
747 void PowerKeySuspendMonitor::BeginPowerkeyScreenOff() const
748 {
749     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
750     if (pms == nullptr) {
751         return;
752     }
753     auto stateMachine = pms->GetPowerStateMachine();
754     if (stateMachine == nullptr) {
755         return;
756     }
757     auto stateAction = stateMachine->GetStateAction();
758     if (stateAction == nullptr) {
759         return;
760     }
761     stateAction->BeginPowerkeyScreenOff();
762 }
763 
764 void PowerKeySuspendMonitor::EndPowerkeyScreenOff() const
765 {
766     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
767     if (pms == nullptr) {
768         return;
769     }
770     auto stateMachine = pms->GetPowerStateMachine();
771     if (stateMachine == nullptr) {
772         return;
773     }
774     auto stateAction = stateMachine->GetStateAction();
775     if (stateAction == nullptr) {
776         return;
777     }
778     stateAction->EndPowerkeyScreenOff();
779 }
780 
781 void PowerKeySuspendMonitor::Cancel()
782 {
783 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
784     if (powerkeyReleaseId_ >= 0) {
785         POWER_HILOGI(FEATURE_SUSPEND, "UnsubscribeKeyEvent: PowerKeySuspendMonitor");
786         InputManager::GetInstance()->UnsubscribeKeyEvent(powerkeyReleaseId_);
787         powerkeyReleaseId_ = -1;
788     }
789 #endif
790 }
791 
792 /** Timeout Implement */
793 bool TimeoutSuspendMonitor::Init()
794 {
795     return true;
796 }
797 
798 void TimeoutSuspendMonitor::Cancel() {}
799 
800 void TimeoutSuspendMonitor::HandleEvent()
801 {
802     POWER_HILOGI(FEATURE_INPUT, "TimeoutSuspendMonitor HandleEvent.");
803     Notify();
804 }
805 
806 /** LidSuspendMonitor Implement */
807 
808 bool LidSuspendMonitor::Init()
809 {
810     return true;
811 }
812 
813 void LidSuspendMonitor::Cancel() {}
814 
815 /** SwitchSuspendMonitor Implement */
816 
817 bool SwitchSuspendMonitor::Init()
818 {
819     return true;
820 }
821 
822 void SwitchSuspendMonitor::Cancel() {}
823 } // namespace PowerMgr
824 } // namespace OHOS
825