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