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