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