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