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