• 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 #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     if (sources->GetParseErrorFlag()) {
219         POWER_HILOGI(FEATURE_SUSPEND, "Parse failed, call GetSuspendSourcesByConfig again");
220         jsonStr = SuspendSourceParser::GetSuspendSourcesByConfig();
221         sources = SuspendSourceParser::ParseSources(jsonStr);
222     }
223     if (sources == nullptr) {
224         POWER_HILOGE(COMP_SVC, "get SuspendSources fail");
225         return;
226     }
227     std::vector<SuspendSource> updateSourceList = sources->GetSourceList();
228     if (updateSourceList.size() == 0) {
229         return;
230     }
231     sourceList_ = updateSourceList;
232     POWER_HILOGI(COMP_SVC, "start updateListener");
233     Cancel();
234     uint32_t id = 0;
235     for (auto source = sourceList_.begin(); source != sourceList_.end(); source++, id++) {
236         std::shared_ptr<SuspendMonitor> monitor = SuspendMonitor::CreateMonitor(*source);
237         POWER_HILOGI(FEATURE_SUSPEND, "UpdateFunc CreateMonitor[%{public}u] reason=%{public}d",
238             id, source->GetReason());
239         if (monitor != nullptr && monitor->Init()) {
240             monitor->RegisterListener([this](SuspendDeviceType reason, uint32_t action, uint32_t delay) {
241                 this->ControlListener(reason, action, delay);
242             });
243             g_monitorMutex.lock();
244             monitorMap_.emplace(monitor->GetReason(), monitor);
245             g_monitorMutex.unlock();
246         }
247     }
248 }
249 
RegisterSettingsObserver()250 void SuspendController::RegisterSettingsObserver()
251 {
252 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
253     if (g_suspendSourcesKeyAcObserver && g_suspendSourcesKeyDcObserver) {
254 #else
255     if (g_suspendSourcesKeyObserver) {
256 #endif
257         POWER_HILOGE(FEATURE_POWER_STATE, "suspend sources key observer is already registered");
258         return;
259     }
260     SettingObserver::UpdateFunc updateFunc = [&](const std::string&) {
261         SuspendController::UpdateSuspendSources();
262     };
263 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
264     if (g_suspendSourcesKeyAcObserver == nullptr) {
265         g_suspendSourcesKeyAcObserver = SettingHelper::RegisterSettingAcSuspendSourcesObserver(updateFunc);
266     }
267     if (g_suspendSourcesKeyDcObserver == nullptr) {
268         g_suspendSourcesKeyDcObserver = SettingHelper::RegisterSettingDcSuspendSourcesObserver(updateFunc);
269     }
270 #else
271     g_suspendSourcesKeyObserver = SettingHelper::RegisterSettingSuspendSourcesObserver(updateFunc);
272 #endif
273     POWER_HILOGI(FEATURE_POWER_STATE, "register setting observer fin");
274 }
275 
276 void SuspendController::UnregisterSettingsObserver()
277 {
278 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
279     if (g_suspendSourcesKeyAcObserver) {
280         SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyAcObserver);
281         g_suspendSourcesKeyAcObserver = nullptr;
282     }
283     if (g_suspendSourcesKeyDcObserver) {
284         SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyDcObserver);
285         g_suspendSourcesKeyDcObserver = nullptr;
286     }
287 #else
288     if (g_suspendSourcesKeyObserver) {
289         SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyObserver);
290         g_suspendSourcesKeyObserver = nullptr;
291     }
292 #endif
293 }
294 
295 void SuspendController::Execute()
296 {
297     HandleAction(GetLastReason(), GetLastAction());
298 }
299 
300 void SuspendController::Cancel()
301 {
302     g_monitorMutex.lock();
303     for (auto monitor = monitorMap_.begin(); monitor != monitorMap_.end(); monitor++) {
304         monitor->second->Cancel();
305     }
306     monitorMap_.clear();
307     g_monitorMutex.unlock();
308 }
309 
310 void SuspendController::StopSleep()
311 {
312     ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
313     if (ffrtTimer_ != nullptr) {
314         ffrtTimer_->CancelTimer(TIMER_ID_SLEEP);
315     }
316     sleepTime_ = -1;
317     sleepAction_ = static_cast<uint32_t>(SuspendAction::ACTION_NONE);
318     ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
319 }
320 
321 void SuspendController::HandleEvent(int64_t delayTime)
322 {
323     FFRTTask task = [&]() {
324         g_monitorMutex.lock();
325         auto timeoutSuspendMonitor = monitorMap_.find(SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT);
326         if (timeoutSuspendMonitor == monitorMap_.end()) {
327             g_monitorMutex.unlock();
328             return;
329         }
330 
331         auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
332         if (pms != nullptr) {
333             if (pms->CheckDialogFlag()) {
334                 POWER_HILOGI(FEATURE_SUSPEND, "Reset long press flag before suspending device by timeout");
335             }
336         }
337         if (stateMachine_ != nullptr) {
338             int32_t timeout = stateMachine_->GetDisplayOffTime();
339             POWER_HILOGI(FEATURE_INPUT, "This time of timeout is %{public}d ms", timeout);
340         }
341         g_monitorMutex.unlock();
342         auto monitor = timeoutSuspendMonitor->second;
343         monitor->HandleEvent();
344     };
345     if (ffrtTimer_ != nullptr) {
346         ffrtTimer_->SetTimer(TIMER_ID_USER_ACTIVITY_OFF, task, delayTime);
347     } else {
348         POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}s) failed, timer is null",
349             __func__, std::to_string(delayTime).c_str());
350     }
351 }
352 
353 void SuspendController::CancelEvent()
354 {
355     if (ffrtTimer_ != nullptr) {
356         ffrtTimer_->CancelTimer(TIMER_ID_USER_ACTIVITY_OFF);
357     }
358 }
359 
360 void SuspendController::RecordPowerKeyDown(bool interrupting)
361 {
362     if (stateMachine_ == nullptr) {
363         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
364         return;
365     }
366     bool isScreenOn = stateMachine_->IsScreenOn();
367     POWER_HILOGI(FEATURE_SUSPEND, "Suspend record key down action isScreenOn=%{public}d", isScreenOn);
368     if (!isScreenOn) {
369         powerkeyDownWhenScreenOff_ = true;
370     } else {
371         if (interrupting) {
372             POWER_HILOGI(FEATURE_SUSPEND, "Suspend record key down after interrupting screen off");
373         }
374         powerkeyDownWhenScreenOff_ = interrupting;
375     }
376 
377     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
378     if (pms == nullptr) {
379         return;
380     }
381 
382     if (pms->CheckDialogFlag()) {
383         return;
384     }
385 }
386 
387 bool SuspendController::GetPowerkeyDownWhenScreenOff()
388 {
389     bool powerKeyDown = powerkeyDownWhenScreenOff_;
390     powerkeyDownWhenScreenOff_ = false;
391     return powerKeyDown;
392 }
393 
394 void SuspendController::SuspendWhenScreenOff(SuspendDeviceType reason, uint32_t action, uint32_t delay)
395 {
396     if (reason != SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH) {
397         POWER_HILOGI(FEATURE_SUSPEND, "Do nothing for reason %{public}d", reason);
398         return;
399     }
400     if (stateMachine_ == nullptr) {
401         return;
402     }
403 
404     POWER_HILOGI(FEATURE_SUSPEND,
405         "Suspend when screen off, reason=%{public}d, action=%{public}u, "
406         "delay=%{public}u, state=%{public}d, type=%{public}u",
407         reason, action, delay, stateMachine_->GetState(), sleepType_);
408     switch (stateMachine_->GetState()) {
409         case PowerState::INACTIVE:
410             StopSleep();
411             StartSleepTimer(reason, action, delay);
412             break;
413         case PowerState::SLEEP:
414             if (action != static_cast<uint32_t>(SuspendAction::ACTION_FORCE_SUSPEND)) {
415                 break;
416             }
417             if (sleepType_ == static_cast<uint32_t>(SuspendAction::ACTION_AUTO_SUSPEND)) {
418                 SystemSuspendController::GetInstance().Wakeup();
419                 StartSleepTimer(reason, action, 0);
420             } else if (sleepType_ == static_cast<uint32_t>(SuspendAction::ACTION_FORCE_SUSPEND)) {
421                 if (stateMachine_->IsSwitchOpen()) {
422                     POWER_HILOGI(FEATURE_SUSPEND, "switch off event is ignored.");
423                     return;
424                 }
425                 SystemSuspendController::GetInstance().Wakeup();
426                 SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, true);
427             } else {
428                 POWER_HILOGD(FEATURE_SUSPEND, "Nothing to do for no suspend");
429             }
430             break;
431         default:
432             break;
433     }
434 }
435 
436 void SuspendController::ControlListener(SuspendDeviceType reason, uint32_t action, uint32_t delay)
437 {
438     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
439     if (pms == nullptr) {
440         return;
441     }
442 
443     if (pms->CheckDialogAndShuttingDown()) {
444         return;
445     }
446 
447     if (!pms->IsScreenOn()) {
448         SuspendWhenScreenOff(reason, action, delay);
449         return;
450     }
451 
452     pid_t pid = IPCSkeleton::GetCallingPid();
453     auto uid = IPCSkeleton::GetCallingUid();
454     POWER_HILOGI(FEATURE_SUSPEND,
455         "[UL_POWER] Try to suspend device, pid=%{public}d, uid=%{public}d, reason=%{public}d, action=%{public}u, "
456         "delay=%{public}u",
457         pid, uid, reason, action, delay);
458     bool force = true;
459     if (reason == SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT) {
460         force = false;
461     }
462     if (stateMachine_ == nullptr) {
463         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
464         return;
465     }
466     bool ret = stateMachine_->SetState(
467         PowerState::INACTIVE, stateMachine_->GetReasionBySuspendType(static_cast<SuspendDeviceType>(reason)), force);
468     if (ret) {
469         StartSleepTimer(reason, action, delay);
470     }
471 }
472 
473 void SuspendController::StartSleepTimer(SuspendDeviceType reason, uint32_t action, uint32_t delay)
474 {
475     if (static_cast<SuspendAction>(action) == SuspendAction::ACTION_AUTO_SUSPEND) {
476         if (stateMachine_->GetSleepTime() < 0) {
477             POWER_HILOGI(FEATURE_SUSPEND, "sleeptime less than zero, no need suspend");
478             return;
479         }
480     }
481 
482     int64_t tick = GetTickCount();
483     int64_t timeout = tick + static_cast<int64_t>(delay);
484     if (timeout < tick) {
485         POWER_HILOGE(FEATURE_SUSPEND, "Sleep timer overflow with tick = %{public}s, delay = %{public}u",
486             std::to_string(tick).c_str(), delay);
487         return;
488     }
489 
490     ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
491     if ((timeout > sleepTime_) && (sleepTime_ != -1)) {
492         POWER_HILOGI(FEATURE_SUSPEND, "already have a sleep event (%{public}" PRId64 " > %{public}" PRId64 ")", timeout,
493             sleepTime_);
494         ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
495         return;
496     }
497     sleepTime_ = timeout;
498     sleepReason_ = reason;
499     sleepAction_ = action;
500     sleepDuration_ = delay;
501     sleepType_ = action;
502     FFRTTask task = [this, reason, action] {
503         HandleAction(reason, action);
504     };
505 
506     if (ffrtTimer_ != nullptr) {
507         ffrtTimer_->SetTimer(TIMER_ID_SLEEP, task, delay);
508     } else {
509         POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}u) failed, timer is null", __func__, delay);
510     }
511     ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
512 }
513 
514 void SuspendController::HandleAction(SuspendDeviceType reason, uint32_t action)
515 {
516     switch (static_cast<SuspendAction>(action)) {
517         case SuspendAction::ACTION_AUTO_SUSPEND:
518             HandleAutoSleep(reason);
519             break;
520         case SuspendAction::ACTION_FORCE_SUSPEND:
521             HandleForceSleep(reason);
522             break;
523         case SuspendAction::ACTION_HIBERNATE:
524             HandleHibernate(reason);
525             break;
526         case SuspendAction::ACTION_SHUTDOWN:
527             HandleShutdown(reason);
528             break;
529         case SuspendAction::ACTION_NONE:
530         default:
531             break;
532     }
533     ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
534     sleepTime_ = -1;
535     sleepAction_ = static_cast<uint32_t>(SuspendAction::ACTION_NONE);
536     ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
537 }
538 
539 void SuspendController::HandleAutoSleep(SuspendDeviceType reason)
540 {
541     POWER_HILOGI(FEATURE_SUSPEND, "auto suspend by reason=%{public}d", reason);
542 
543     if (stateMachine_ == nullptr) {
544         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
545         return;
546     }
547     bool ret = stateMachine_->SetState(
548         PowerState::SLEEP, stateMachine_->GetReasionBySuspendType(reason));
549     if (ret) {
550         POWER_HILOGI(FEATURE_SUSPEND, "State changed, set sleep timer");
551         TriggerSyncSleepCallback(false);
552         SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, false);
553     } else {
554         POWER_HILOGI(FEATURE_SUSPEND, "auto suspend: State change failed");
555     }
556 }
557 
558 void SuspendController::HandleForceSleep(SuspendDeviceType reason)
559 {
560     POWER_HILOGI(FEATURE_SUSPEND, "force suspend by reason=%{public}d", reason);
561     if (stateMachine_ == nullptr) {
562         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
563         return;
564     }
565 
566 #ifdef POWER_MANAGER_ENABLE_FORCE_SLEEP_BROADCAST
567     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
568     if (pms != nullptr && pms->GetSuspendController() != nullptr) {
569         pms->GetSuspendController()->SetForceSleepingFlag(true);
570         POWER_HILOGI(FEATURE_SUSPEND, "Set flag of force sleeping to true");
571     } else {
572         POWER_HILOGE(FEATURE_SUSPEND, "Failed to set flag of force sleeping, pms or suspendController is nullptr");
573     }
574 #endif
575     bool ret = stateMachine_->SetState(PowerState::SLEEP,
576         stateMachine_->GetReasionBySuspendType(reason), true);
577     if (ret) {
578         POWER_HILOGI(FEATURE_SUSPEND, "State changed, system suspend");
579         onForceSleep = true;
580         TriggerSyncSleepCallback(false);
581 
582         FFRTTask task = [this, reason] {
583             SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, true);
584         };
585         if (ffrtTimer_ != nullptr) {
586             ffrtTimer_->SetTimer(TIMER_ID_SLEEP, task, FORCE_SLEEP_DELAY_MS);
587         } else {
588             POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}d) failed, timer is null",
589                 __func__, FORCE_SLEEP_DELAY_MS);
590         }
591     } else {
592         POWER_HILOGI(FEATURE_SUSPEND, "force suspend: State change failed");
593     }
594 }
595 
596 void SuspendController::HandleHibernate(SuspendDeviceType reason)
597 {
598     POWER_HILOGI(FEATURE_SUSPEND, "force suspend by reason=%{public}d", reason);
599     if (stateMachine_ == nullptr) {
600         POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
601         return;
602     }
603     bool ret = stateMachine_->SetState(
604         PowerState::HIBERNATE, stateMachine_->GetReasionBySuspendType(reason), true);
605     if (ret) {
606         POWER_HILOGI(FEATURE_SUSPEND, "State changed, call hibernate");
607     } else {
608         POWER_HILOGI(FEATURE_SUSPEND, "Hibernate: State change failed");
609     }
610 }
611 
612 void SuspendController::HandleShutdown(SuspendDeviceType reason)
613 {
614     POWER_HILOGI(FEATURE_SUSPEND, "shutdown by reason=%{public}d", reason);
615     shutdownController_->Shutdown(std::to_string(static_cast<uint32_t>(reason)));
616 }
617 
618 void SuspendController::Reset()
619 {
620     ffrtTimer_.reset();
621 }
622 
623 const std::shared_ptr<SuspendMonitor> SuspendMonitor::CreateMonitor(SuspendSource& source)
624 {
625     SuspendDeviceType reason = source.GetReason();
626     std::shared_ptr<SuspendMonitor> monitor = nullptr;
627     switch (reason) {
628         case SuspendDeviceType::SUSPEND_DEVICE_REASON_POWER_KEY:
629             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<PowerKeySuspendMonitor>(source));
630             break;
631         case SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT:
632             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<TimeoutSuspendMonitor>(source));
633             break;
634         case SuspendDeviceType::SUSPEND_DEVICE_REASON_LID:
635             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<LidSuspendMonitor>(source));
636             break;
637         case SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH:
638             monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<SwitchSuspendMonitor>(source));
639             break;
640         default:
641             POWER_HILOGE(FEATURE_SUSPEND, "CreateMonitor : Invalid reason=%{public}d", reason);
642             break;
643     }
644     return monitor;
645 }
646 
647 /** PowerKeySuspendMonitor Implement */
648 bool PowerKeySuspendMonitor::Init()
649 {
650 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
651     if (powerkeyReleaseId_ >= 0) {
652         return true;
653     }
654     std::shared_ptr<OHOS::MMI::KeyOption> keyOption = std::make_shared<OHOS::MMI::KeyOption>();
655     std::set<int32_t> preKeys;
656 
657     keyOption.reset();
658     keyOption = std::make_shared<OHOS::MMI::KeyOption>();
659     keyOption->SetPreKeys(preKeys);
660     keyOption->SetFinalKey(OHOS::MMI::KeyEvent::KEYCODE_POWER);
661     keyOption->SetFinalKeyDown(false);
662     keyOption->SetFinalKeyDownDuration(0);
663     powerkeyReleaseId_ = InputManager::GetInstance()->SubscribeKeyEvent(
664         keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) {
665             POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER] Received powerkey up");
666 
667             static int64_t lastPowerkeyUpTime = 0;
668             int64_t currTime = GetTickCount();
669             if (lastPowerkeyUpTime != 0 && currTime - lastPowerkeyUpTime < POWERKEY_MIN_INTERVAL) {
670                 POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Last powerkey up within 350ms, skip. "
671                     "%{public}" PRId64 ", %{public}" PRId64, currTime, lastPowerkeyUpTime);
672                 return;
673             }
674             lastPowerkeyUpTime = currTime;
675 
676             auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
677             if (pms == nullptr) {
678                 return;
679             }
680             std::shared_ptr<SuspendController> suspendController = pms->GetSuspendController();
681             if (suspendController->GetPowerkeyDownWhenScreenOff()) {
682                 POWER_HILOGI(FEATURE_SUSPEND,
683                     "[UL_POWER] The powerkey was pressed when screenoff, ignore this powerkey up event.");
684                 return;
685             }
686             auto powerkeyScreenOffTask = [*this]() mutable {
687                 Notify();
688                 powerkeyScreenOff_ = false;
689                 EndPowerkeyScreenOff();
690             };
691             BeginPowerkeyScreenOff();
692             powerkeyScreenOff_ = true;
693             ffrt::submit(powerkeyScreenOffTask, {}, {&powerkeyScreenOff_});
694             POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER]submitted screen off ffrt task");
695         });
696     POWER_HILOGI(FEATURE_SUSPEND, "powerkeyReleaseId_=%{public}d", powerkeyReleaseId_);
697     return powerkeyReleaseId_ >= 0 ? true : false;
698 #else
699     return false;
700 #endif
701 }
702 
703 void PowerKeySuspendMonitor::BeginPowerkeyScreenOff() const
704 {
705     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
706     if (pms == nullptr) {
707         return;
708     }
709     auto stateMachine = pms->GetPowerStateMachine();
710     if (stateMachine == nullptr) {
711         return;
712     }
713     auto stateAction = stateMachine->GetStateAction();
714     if (stateAction == nullptr) {
715         return;
716     }
717     stateAction->BeginPowerkeyScreenOff();
718 }
719 
720 void PowerKeySuspendMonitor::EndPowerkeyScreenOff() const
721 {
722     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
723     if (pms == nullptr) {
724         return;
725     }
726     auto stateMachine = pms->GetPowerStateMachine();
727     if (stateMachine == nullptr) {
728         return;
729     }
730     auto stateAction = stateMachine->GetStateAction();
731     if (stateAction == nullptr) {
732         return;
733     }
734     stateAction->EndPowerkeyScreenOff();
735 }
736 
737 void PowerKeySuspendMonitor::Cancel()
738 {
739 #ifdef HAS_MULTIMODALINPUT_INPUT_PART
740     if (powerkeyReleaseId_ >= 0) {
741         POWER_HILOGI(FEATURE_SUSPEND, "UnsubscribeKeyEvent: PowerKeySuspendMonitor");
742         InputManager::GetInstance()->UnsubscribeKeyEvent(powerkeyReleaseId_);
743         powerkeyReleaseId_ = -1;
744     }
745 #endif
746 }
747 
748 /** Timeout Implement */
749 bool TimeoutSuspendMonitor::Init()
750 {
751     return true;
752 }
753 
754 void TimeoutSuspendMonitor::Cancel() {}
755 
756 void TimeoutSuspendMonitor::HandleEvent()
757 {
758     POWER_HILOGI(FEATURE_INPUT, "TimeoutSuspendMonitor HandleEvent.");
759     Notify();
760 }
761 
762 /** LidSuspendMonitor Implement */
763 
764 bool LidSuspendMonitor::Init()
765 {
766     return true;
767 }
768 
769 void LidSuspendMonitor::Cancel() {}
770 
771 /** SwitchSuspendMonitor Implement */
772 
773 bool SwitchSuspendMonitor::Init()
774 {
775     return true;
776 }
777 
778 void SwitchSuspendMonitor::Cancel() {}
779 } // namespace PowerMgr
780 } // namespace OHOS
781