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