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