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