15ccb8f90Sopenharmony_ci/*
25ccb8f90Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
35ccb8f90Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
45ccb8f90Sopenharmony_ci * you may not use this file except in compliance with the License.
55ccb8f90Sopenharmony_ci * You may obtain a copy of the License at
65ccb8f90Sopenharmony_ci *
75ccb8f90Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
85ccb8f90Sopenharmony_ci *
95ccb8f90Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
105ccb8f90Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
115ccb8f90Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125ccb8f90Sopenharmony_ci * See the License for the specific language governing permissions and
135ccb8f90Sopenharmony_ci * limitations under the License.
145ccb8f90Sopenharmony_ci */
155ccb8f90Sopenharmony_ci
165ccb8f90Sopenharmony_ci#include "suspend_controller.h"
175ccb8f90Sopenharmony_ci#include <datetime_ex.h>
185ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
195ccb8f90Sopenharmony_ci#include <display_manager_lite.h>
205ccb8f90Sopenharmony_ci#endif
215ccb8f90Sopenharmony_ci#ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
225ccb8f90Sopenharmony_ci#include <hisysevent.h>
235ccb8f90Sopenharmony_ci#endif
245ccb8f90Sopenharmony_ci#ifdef HAS_MULTIMODALINPUT_INPUT_PART
255ccb8f90Sopenharmony_ci#include <input_manager.h>
265ccb8f90Sopenharmony_ci#endif
275ccb8f90Sopenharmony_ci#include <ipc_skeleton.h>
285ccb8f90Sopenharmony_ci#include <securec.h>
295ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
305ccb8f90Sopenharmony_ci#include <screen_manager_lite.h>
315ccb8f90Sopenharmony_ci#endif
325ccb8f90Sopenharmony_ci#include "power_log.h"
335ccb8f90Sopenharmony_ci#include "power_mgr_service.h"
345ccb8f90Sopenharmony_ci#include "power_state_callback_stub.h"
355ccb8f90Sopenharmony_ci#include "setting_helper.h"
365ccb8f90Sopenharmony_ci#include "system_suspend_controller.h"
375ccb8f90Sopenharmony_ci#include "wakeup_controller.h"
385ccb8f90Sopenharmony_ci
395ccb8f90Sopenharmony_cinamespace OHOS {
405ccb8f90Sopenharmony_cinamespace PowerMgr {
415ccb8f90Sopenharmony_ciusing namespace OHOS::MMI;
425ccb8f90Sopenharmony_cinamespace {
435ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
445ccb8f90Sopenharmony_cisptr<SettingObserver> g_suspendSourcesKeyAcObserver = nullptr;
455ccb8f90Sopenharmony_cisptr<SettingObserver> g_suspendSourcesKeyDcObserver = nullptr;
465ccb8f90Sopenharmony_ci#else
475ccb8f90Sopenharmony_cisptr<SettingObserver> g_suspendSourcesKeyObserver = nullptr;
485ccb8f90Sopenharmony_ci#endif
495ccb8f90Sopenharmony_ciFFRTMutex g_monitorMutex;
505ccb8f90Sopenharmony_ciconstexpr int64_t POWERKEY_MIN_INTERVAL = 350; // ms
515ccb8f90Sopenharmony_ci} // namespace
525ccb8f90Sopenharmony_ci
535ccb8f90Sopenharmony_cistd::atomic_bool onForceSleep = false;
545ccb8f90Sopenharmony_ci
555ccb8f90Sopenharmony_ci/** SuspendController Implement */
565ccb8f90Sopenharmony_ciSuspendController::SuspendController(const std::shared_ptr<ShutdownController>& shutdownController,
575ccb8f90Sopenharmony_ci    const std::shared_ptr<PowerStateMachine>& stateMachine, const std::shared_ptr<FFRTTimer>& ffrtTimer)
585ccb8f90Sopenharmony_ci{
595ccb8f90Sopenharmony_ci    shutdownController_ = shutdownController;
605ccb8f90Sopenharmony_ci    stateMachine_ = stateMachine;
615ccb8f90Sopenharmony_ci    ffrtTimer_ = ffrtTimer;
625ccb8f90Sopenharmony_ci}
635ccb8f90Sopenharmony_ci
645ccb8f90Sopenharmony_ciSuspendController::~SuspendController()
655ccb8f90Sopenharmony_ci{
665ccb8f90Sopenharmony_ci    UnregisterSettingsObserver();
675ccb8f90Sopenharmony_ci    ffrtTimer_.reset();
685ccb8f90Sopenharmony_ci}
695ccb8f90Sopenharmony_ci
705ccb8f90Sopenharmony_civoid SuspendController::AddCallback(const sptr<ISyncSleepCallback>& callback, SleepPriority priority)
715ccb8f90Sopenharmony_ci{
725ccb8f90Sopenharmony_ci    RETURN_IF(callback == nullptr)
735ccb8f90Sopenharmony_ci    SleepCallbackHolder::GetInstance().AddCallback(callback, priority);
745ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND,
755ccb8f90Sopenharmony_ci        "sync sleep callback added, priority=%{public}u, pid=%{public}d, uid=%{public}d", priority,
765ccb8f90Sopenharmony_ci        IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
775ccb8f90Sopenharmony_ci}
785ccb8f90Sopenharmony_ci
795ccb8f90Sopenharmony_civoid SuspendController::RemoveCallback(const sptr<ISyncSleepCallback>& callback)
805ccb8f90Sopenharmony_ci{
815ccb8f90Sopenharmony_ci    RETURN_IF(callback == nullptr)
825ccb8f90Sopenharmony_ci    SleepCallbackHolder::GetInstance().RemoveCallback(callback);
835ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND,
845ccb8f90Sopenharmony_ci        "sync sleep callback removed, pid=%{public}d, uid=%{public}d",
855ccb8f90Sopenharmony_ci        IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
865ccb8f90Sopenharmony_ci}
875ccb8f90Sopenharmony_ci
885ccb8f90Sopenharmony_civoid SuspendController::TriggerSyncSleepCallback(bool isWakeup)
895ccb8f90Sopenharmony_ci{
905ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND,
915ccb8f90Sopenharmony_ci        "TriggerSyncSleepCallback, isWakeup=%{public}d, onForceSleep=%{public}d",
925ccb8f90Sopenharmony_ci        isWakeup, onForceSleep == true);
935ccb8f90Sopenharmony_ci    auto highPriorityCallbacks = SleepCallbackHolder::GetInstance().GetHighPriorityCallbacks();
945ccb8f90Sopenharmony_ci    TriggerSyncSleepCallbackInner(highPriorityCallbacks, "High", isWakeup);
955ccb8f90Sopenharmony_ci    auto defaultPriorityCallbacks = SleepCallbackHolder::GetInstance().GetDefaultPriorityCallbacks();
965ccb8f90Sopenharmony_ci    TriggerSyncSleepCallbackInner(defaultPriorityCallbacks, "Default", isWakeup);
975ccb8f90Sopenharmony_ci    auto lowPriorityCallbacks = SleepCallbackHolder::GetInstance().GetLowPriorityCallbacks();
985ccb8f90Sopenharmony_ci    TriggerSyncSleepCallbackInner(lowPriorityCallbacks, "Low", isWakeup);
995ccb8f90Sopenharmony_ci
1005ccb8f90Sopenharmony_ci    if (isWakeup && onForceSleep) {
1015ccb8f90Sopenharmony_ci        onForceSleep = false;
1025ccb8f90Sopenharmony_ci    }
1035ccb8f90Sopenharmony_ci}
1045ccb8f90Sopenharmony_ci
1055ccb8f90Sopenharmony_civoid SuspendController::TriggerSyncSleepCallbackInner(std::set<sptr<ISyncSleepCallback>>& callbacks,
1065ccb8f90Sopenharmony_ci    const std::string& priority, bool isWakeup)
1075ccb8f90Sopenharmony_ci{
1085ccb8f90Sopenharmony_ci    uint32_t id = 0;
1095ccb8f90Sopenharmony_ci    for (auto &callback : callbacks) {
1105ccb8f90Sopenharmony_ci        if (callback != nullptr) {
1115ccb8f90Sopenharmony_ci            int64_t start = GetTickCount();
1125ccb8f90Sopenharmony_ci            isWakeup ? callback->OnSyncWakeup(onForceSleep) : callback->OnSyncSleep(onForceSleep);
1135ccb8f90Sopenharmony_ci            int64_t cost = GetTickCount() - start;
1145ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND,
1155ccb8f90Sopenharmony_ci                "Trigger %{public}s SyncSleepCallback[%{public}u] success, cost=%{public}" PRId64,
1165ccb8f90Sopenharmony_ci                priority.c_str(), ++id, cost);
1175ccb8f90Sopenharmony_ci        }
1185ccb8f90Sopenharmony_ci    }
1195ccb8f90Sopenharmony_ci}
1205ccb8f90Sopenharmony_ci
1215ccb8f90Sopenharmony_ciclass SuspendPowerStateCallback : public PowerStateCallbackStub {
1225ccb8f90Sopenharmony_cipublic:
1235ccb8f90Sopenharmony_ci    explicit SuspendPowerStateCallback(std::shared_ptr<SuspendController> controller) : controller_(controller) {};
1245ccb8f90Sopenharmony_ci    virtual ~SuspendPowerStateCallback() = default;
1255ccb8f90Sopenharmony_ci    void OnPowerStateChanged(PowerState state) override
1265ccb8f90Sopenharmony_ci    {
1275ccb8f90Sopenharmony_ci        auto controller = controller_.lock();
1285ccb8f90Sopenharmony_ci        if (controller == nullptr) {
1295ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND, "OnPowerStateChanged: No controller");
1305ccb8f90Sopenharmony_ci            return;
1315ccb8f90Sopenharmony_ci        }
1325ccb8f90Sopenharmony_ci        if (state == PowerState::AWAKE) {
1335ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND, "Turn awake, stop sleep timer");
1345ccb8f90Sopenharmony_ci            controller->StopSleep();
1355ccb8f90Sopenharmony_ci        }
1365ccb8f90Sopenharmony_ci    }
1375ccb8f90Sopenharmony_ci
1385ccb8f90Sopenharmony_ciprivate:
1395ccb8f90Sopenharmony_ci    std::weak_ptr<SuspendController> controller_;
1405ccb8f90Sopenharmony_ci};
1415ccb8f90Sopenharmony_ci
1425ccb8f90Sopenharmony_civoid SuspendController::Init()
1435ccb8f90Sopenharmony_ci{
1445ccb8f90Sopenharmony_ci    std::lock_guard lock(mutex_);
1455ccb8f90Sopenharmony_ci    std::shared_ptr<SuspendSources> sources = SuspendSourceParser::ParseSources();
1465ccb8f90Sopenharmony_ci    sourceList_ = sources->GetSourceList();
1475ccb8f90Sopenharmony_ci    if (sourceList_.empty()) {
1485ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "InputManager is null");
1495ccb8f90Sopenharmony_ci        return;
1505ccb8f90Sopenharmony_ci    }
1515ccb8f90Sopenharmony_ci
1525ccb8f90Sopenharmony_ci    for (auto source = sourceList_.begin(); source != sourceList_.end(); source++) {
1535ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "registered type=%{public}u action=%{public}u delayMs=%{public}u",
1545ccb8f90Sopenharmony_ci            (*source).GetReason(), (*source).GetAction(), (*source).GetDelay());
1555ccb8f90Sopenharmony_ci        std::shared_ptr<SuspendMonitor> monitor = SuspendMonitor::CreateMonitor(*source);
1565ccb8f90Sopenharmony_ci        if (monitor != nullptr && monitor->Init()) {
1575ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND, "monitor init success, type=%{public}u", (*source).GetReason());
1585ccb8f90Sopenharmony_ci            monitor->RegisterListener([this](SuspendDeviceType reason, uint32_t action, uint32_t delay) {
1595ccb8f90Sopenharmony_ci                this->ControlListener(reason, action, delay);
1605ccb8f90Sopenharmony_ci            });
1615ccb8f90Sopenharmony_ci            g_monitorMutex.lock();
1625ccb8f90Sopenharmony_ci            monitorMap_.emplace(monitor->GetReason(), monitor);
1635ccb8f90Sopenharmony_ci            g_monitorMutex.unlock();
1645ccb8f90Sopenharmony_ci        }
1655ccb8f90Sopenharmony_ci    }
1665ccb8f90Sopenharmony_ci    sptr<SuspendPowerStateCallback> callback = new SuspendPowerStateCallback(shared_from_this());
1675ccb8f90Sopenharmony_ci    if (stateMachine_ == nullptr) {
1685ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
1695ccb8f90Sopenharmony_ci        return;
1705ccb8f90Sopenharmony_ci    }
1715ccb8f90Sopenharmony_ci    stateMachine_->RegisterPowerStateCallback(callback);
1725ccb8f90Sopenharmony_ci    RegisterSettingsObserver();
1735ccb8f90Sopenharmony_ci}
1745ccb8f90Sopenharmony_ci
1755ccb8f90Sopenharmony_civoid SuspendController::ExecSuspendMonitorByReason(SuspendDeviceType reason)
1765ccb8f90Sopenharmony_ci{
1775ccb8f90Sopenharmony_ci    FFRTUtils::SubmitTask([this, reason] {
1785ccb8f90Sopenharmony_ci        g_monitorMutex.lock();
1795ccb8f90Sopenharmony_ci        auto suspendMonitor = GetSpecifiedSuspendMonitor(reason);
1805ccb8f90Sopenharmony_ci        if (suspendMonitor == nullptr) {
1815ccb8f90Sopenharmony_ci            POWER_HILOGI(COMP_SVC, "get monitor fail, type: %{public}u", reason);
1825ccb8f90Sopenharmony_ci            g_monitorMutex.unlock();
1835ccb8f90Sopenharmony_ci            return;
1845ccb8f90Sopenharmony_ci        }
1855ccb8f90Sopenharmony_ci        suspendMonitor->Notify();
1865ccb8f90Sopenharmony_ci        g_monitorMutex.unlock();
1875ccb8f90Sopenharmony_ci    });
1885ccb8f90Sopenharmony_ci}
1895ccb8f90Sopenharmony_ci
1905ccb8f90Sopenharmony_civoid SuspendController::UpdateSuspendSources()
1915ccb8f90Sopenharmony_ci{
1925ccb8f90Sopenharmony_ci    POWER_HILOGI(COMP_SVC, "start setting string update");
1935ccb8f90Sopenharmony_ci    std::lock_guard lock(mutex_);
1945ccb8f90Sopenharmony_ci
1955ccb8f90Sopenharmony_ci    auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
1965ccb8f90Sopenharmony_ci    if (pms == nullptr) {
1975ccb8f90Sopenharmony_ci        POWER_HILOGE(COMP_SVC, "get PowerMgrService fail");
1985ccb8f90Sopenharmony_ci        return;
1995ccb8f90Sopenharmony_ci    }
2005ccb8f90Sopenharmony_ci    std::string jsonStr;
2015ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
2025ccb8f90Sopenharmony_ci    if (pms->IsPowerConnected()) {
2035ccb8f90Sopenharmony_ci        jsonStr = SettingHelper::GetSettingAcSuspendSources();
2045ccb8f90Sopenharmony_ci    } else {
2055ccb8f90Sopenharmony_ci        jsonStr = SettingHelper::GetSettingDcSuspendSources();
2065ccb8f90Sopenharmony_ci    }
2075ccb8f90Sopenharmony_ci#else
2085ccb8f90Sopenharmony_ci    jsonStr = SettingHelper::GetSettingSuspendSources();
2095ccb8f90Sopenharmony_ci#endif
2105ccb8f90Sopenharmony_ci    std::shared_ptr<SuspendSources> sources = SuspendSourceParser::ParseSources(jsonStr);
2115ccb8f90Sopenharmony_ci    std::vector<SuspendSource> updateSourceList = sources->GetSourceList();
2125ccb8f90Sopenharmony_ci    if (updateSourceList.size() == 0) {
2135ccb8f90Sopenharmony_ci        return;
2145ccb8f90Sopenharmony_ci    }
2155ccb8f90Sopenharmony_ci    sourceList_ = updateSourceList;
2165ccb8f90Sopenharmony_ci    POWER_HILOGI(COMP_SVC, "start updateListener");
2175ccb8f90Sopenharmony_ci    Cancel();
2185ccb8f90Sopenharmony_ci    uint32_t id = 0;
2195ccb8f90Sopenharmony_ci    for (auto source = sourceList_.begin(); source != sourceList_.end(); source++, id++) {
2205ccb8f90Sopenharmony_ci        std::shared_ptr<SuspendMonitor> monitor = SuspendMonitor::CreateMonitor(*source);
2215ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "UpdateFunc CreateMonitor[%{public}u] reason=%{public}d",
2225ccb8f90Sopenharmony_ci            id, source->GetReason());
2235ccb8f90Sopenharmony_ci        if (monitor != nullptr && monitor->Init()) {
2245ccb8f90Sopenharmony_ci            monitor->RegisterListener([this](SuspendDeviceType reason, uint32_t action, uint32_t delay) {
2255ccb8f90Sopenharmony_ci                this->ControlListener(reason, action, delay);
2265ccb8f90Sopenharmony_ci            });
2275ccb8f90Sopenharmony_ci            g_monitorMutex.lock();
2285ccb8f90Sopenharmony_ci            monitorMap_.emplace(monitor->GetReason(), monitor);
2295ccb8f90Sopenharmony_ci            g_monitorMutex.unlock();
2305ccb8f90Sopenharmony_ci        }
2315ccb8f90Sopenharmony_ci    }
2325ccb8f90Sopenharmony_ci}
2335ccb8f90Sopenharmony_ci
2345ccb8f90Sopenharmony_civoid SuspendController::RegisterSettingsObserver()
2355ccb8f90Sopenharmony_ci{
2365ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
2375ccb8f90Sopenharmony_ci    if (g_suspendSourcesKeyAcObserver && g_suspendSourcesKeyDcObserver) {
2385ccb8f90Sopenharmony_ci#else
2395ccb8f90Sopenharmony_ci    if (g_suspendSourcesKeyObserver) {
2405ccb8f90Sopenharmony_ci#endif
2415ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_POWER_STATE, "suspend sources key observer is already registered");
2425ccb8f90Sopenharmony_ci        return;
2435ccb8f90Sopenharmony_ci    }
2445ccb8f90Sopenharmony_ci    SettingObserver::UpdateFunc updateFunc = [&](const std::string&) {
2455ccb8f90Sopenharmony_ci        SuspendController::UpdateSuspendSources();
2465ccb8f90Sopenharmony_ci    };
2475ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
2485ccb8f90Sopenharmony_ci    if (g_suspendSourcesKeyAcObserver == nullptr) {
2495ccb8f90Sopenharmony_ci        g_suspendSourcesKeyAcObserver = SettingHelper::RegisterSettingAcSuspendSourcesObserver(updateFunc);
2505ccb8f90Sopenharmony_ci    }
2515ccb8f90Sopenharmony_ci    if (g_suspendSourcesKeyDcObserver == nullptr) {
2525ccb8f90Sopenharmony_ci        g_suspendSourcesKeyDcObserver = SettingHelper::RegisterSettingDcSuspendSourcesObserver(updateFunc);
2535ccb8f90Sopenharmony_ci    }
2545ccb8f90Sopenharmony_ci#else
2555ccb8f90Sopenharmony_ci    g_suspendSourcesKeyObserver = SettingHelper::RegisterSettingSuspendSourcesObserver(updateFunc);
2565ccb8f90Sopenharmony_ci#endif
2575ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_POWER_STATE, "register setting observer fin");
2585ccb8f90Sopenharmony_ci}
2595ccb8f90Sopenharmony_ci
2605ccb8f90Sopenharmony_civoid SuspendController::UnregisterSettingsObserver()
2615ccb8f90Sopenharmony_ci{
2625ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
2635ccb8f90Sopenharmony_ci    if (g_suspendSourcesKeyAcObserver) {
2645ccb8f90Sopenharmony_ci        SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyAcObserver);
2655ccb8f90Sopenharmony_ci        g_suspendSourcesKeyAcObserver = nullptr;
2665ccb8f90Sopenharmony_ci    }
2675ccb8f90Sopenharmony_ci    if (g_suspendSourcesKeyDcObserver) {
2685ccb8f90Sopenharmony_ci        SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyDcObserver);
2695ccb8f90Sopenharmony_ci        g_suspendSourcesKeyDcObserver = nullptr;
2705ccb8f90Sopenharmony_ci    }
2715ccb8f90Sopenharmony_ci#else
2725ccb8f90Sopenharmony_ci    if (g_suspendSourcesKeyObserver) {
2735ccb8f90Sopenharmony_ci        SettingHelper::UnregisterSettingObserver(g_suspendSourcesKeyObserver);
2745ccb8f90Sopenharmony_ci        g_suspendSourcesKeyObserver = nullptr;
2755ccb8f90Sopenharmony_ci    }
2765ccb8f90Sopenharmony_ci#endif
2775ccb8f90Sopenharmony_ci}
2785ccb8f90Sopenharmony_ci
2795ccb8f90Sopenharmony_civoid SuspendController::Execute()
2805ccb8f90Sopenharmony_ci{
2815ccb8f90Sopenharmony_ci    HandleAction(GetLastReason(), GetLastAction());
2825ccb8f90Sopenharmony_ci}
2835ccb8f90Sopenharmony_ci
2845ccb8f90Sopenharmony_civoid SuspendController::Cancel()
2855ccb8f90Sopenharmony_ci{
2865ccb8f90Sopenharmony_ci    g_monitorMutex.lock();
2875ccb8f90Sopenharmony_ci    for (auto monitor = monitorMap_.begin(); monitor != monitorMap_.end(); monitor++) {
2885ccb8f90Sopenharmony_ci        monitor->second->Cancel();
2895ccb8f90Sopenharmony_ci    }
2905ccb8f90Sopenharmony_ci    monitorMap_.clear();
2915ccb8f90Sopenharmony_ci    g_monitorMutex.unlock();
2925ccb8f90Sopenharmony_ci}
2935ccb8f90Sopenharmony_ci
2945ccb8f90Sopenharmony_civoid SuspendController::StopSleep()
2955ccb8f90Sopenharmony_ci{
2965ccb8f90Sopenharmony_ci    ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
2975ccb8f90Sopenharmony_ci    if (ffrtTimer_ != nullptr) {
2985ccb8f90Sopenharmony_ci        ffrtTimer_->CancelTimer(TIMER_ID_SLEEP);
2995ccb8f90Sopenharmony_ci    }
3005ccb8f90Sopenharmony_ci    sleepTime_ = -1;
3015ccb8f90Sopenharmony_ci    sleepAction_ = static_cast<uint32_t>(SuspendAction::ACTION_NONE);
3025ccb8f90Sopenharmony_ci    ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
3035ccb8f90Sopenharmony_ci}
3045ccb8f90Sopenharmony_ci
3055ccb8f90Sopenharmony_civoid SuspendController::HandleEvent(int64_t delayTime)
3065ccb8f90Sopenharmony_ci{
3075ccb8f90Sopenharmony_ci    FFRTTask task = [&]() {
3085ccb8f90Sopenharmony_ci        g_monitorMutex.lock();
3095ccb8f90Sopenharmony_ci        auto timeoutSuspendMonitor = GetSpecifiedSuspendMonitor(SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT);
3105ccb8f90Sopenharmony_ci        if (timeoutSuspendMonitor == nullptr) {
3115ccb8f90Sopenharmony_ci            g_monitorMutex.unlock();
3125ccb8f90Sopenharmony_ci            return;
3135ccb8f90Sopenharmony_ci        }
3145ccb8f90Sopenharmony_ci
3155ccb8f90Sopenharmony_ci        auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
3165ccb8f90Sopenharmony_ci        if (pms != nullptr) {
3175ccb8f90Sopenharmony_ci            if (pms->CheckDialogFlag()) {
3185ccb8f90Sopenharmony_ci                POWER_HILOGI(FEATURE_SUSPEND, "Reset long press flag before suspending device by timeout");
3195ccb8f90Sopenharmony_ci            }
3205ccb8f90Sopenharmony_ci        }
3215ccb8f90Sopenharmony_ci        if (stateMachine_ != nullptr) {
3225ccb8f90Sopenharmony_ci            int32_t timeout = stateMachine_->GetDisplayOffTime();
3235ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_INPUT, "This time of timeout is %{public}d ms", timeout);
3245ccb8f90Sopenharmony_ci        }
3255ccb8f90Sopenharmony_ci        g_monitorMutex.unlock();
3265ccb8f90Sopenharmony_ci        timeoutSuspendMonitor->HandleEvent();
3275ccb8f90Sopenharmony_ci    };
3285ccb8f90Sopenharmony_ci    if (ffrtTimer_ != nullptr) {
3295ccb8f90Sopenharmony_ci        ffrtTimer_->SetTimer(TIMER_ID_USER_ACTIVITY_OFF, task, delayTime);
3305ccb8f90Sopenharmony_ci    } else {
3315ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}s) failed, timer is null", __func__,
3325ccb8f90Sopenharmony_ci            std::to_string(delayTime).c_str());
3335ccb8f90Sopenharmony_ci    }
3345ccb8f90Sopenharmony_ci}
3355ccb8f90Sopenharmony_ci
3365ccb8f90Sopenharmony_civoid SuspendController::CancelEvent()
3375ccb8f90Sopenharmony_ci{
3385ccb8f90Sopenharmony_ci    if (ffrtTimer_ != nullptr) {
3395ccb8f90Sopenharmony_ci        ffrtTimer_->CancelTimer(TIMER_ID_USER_ACTIVITY_OFF);
3405ccb8f90Sopenharmony_ci    }
3415ccb8f90Sopenharmony_ci}
3425ccb8f90Sopenharmony_ci
3435ccb8f90Sopenharmony_civoid SuspendController::RecordPowerKeyDown(bool interrupting)
3445ccb8f90Sopenharmony_ci{
3455ccb8f90Sopenharmony_ci    if (stateMachine_ == nullptr) {
3465ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
3475ccb8f90Sopenharmony_ci        return;
3485ccb8f90Sopenharmony_ci    }
3495ccb8f90Sopenharmony_ci    bool isScreenOn = stateMachine_->IsScreenOn();
3505ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND, "Suspend record key down action isScreenOn=%{public}d", isScreenOn);
3515ccb8f90Sopenharmony_ci    if (!isScreenOn) {
3525ccb8f90Sopenharmony_ci        powerkeyDownWhenScreenOff_ = true;
3535ccb8f90Sopenharmony_ci    } else {
3545ccb8f90Sopenharmony_ci        if (interrupting) {
3555ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND, "Suspend record key down after interrupting screen off");
3565ccb8f90Sopenharmony_ci        }
3575ccb8f90Sopenharmony_ci        powerkeyDownWhenScreenOff_ = interrupting;
3585ccb8f90Sopenharmony_ci    }
3595ccb8f90Sopenharmony_ci
3605ccb8f90Sopenharmony_ci    auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
3615ccb8f90Sopenharmony_ci    if (pms == nullptr) {
3625ccb8f90Sopenharmony_ci        return;
3635ccb8f90Sopenharmony_ci    }
3645ccb8f90Sopenharmony_ci
3655ccb8f90Sopenharmony_ci    if (pms->CheckDialogFlag()) {
3665ccb8f90Sopenharmony_ci        return;
3675ccb8f90Sopenharmony_ci    }
3685ccb8f90Sopenharmony_ci}
3695ccb8f90Sopenharmony_ci
3705ccb8f90Sopenharmony_cibool SuspendController::GetPowerkeyDownWhenScreenOff()
3715ccb8f90Sopenharmony_ci{
3725ccb8f90Sopenharmony_ci    bool powerKeyDown = powerkeyDownWhenScreenOff_;
3735ccb8f90Sopenharmony_ci    powerkeyDownWhenScreenOff_ = false;
3745ccb8f90Sopenharmony_ci    return powerKeyDown;
3755ccb8f90Sopenharmony_ci}
3765ccb8f90Sopenharmony_ci
3775ccb8f90Sopenharmony_civoid SuspendController::SuspendWhenScreenOff(SuspendDeviceType reason, uint32_t action, uint32_t delay)
3785ccb8f90Sopenharmony_ci{
3795ccb8f90Sopenharmony_ci    if (reason != SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH) {
3805ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "SuspendWhenScreenOff: Do nothing for reason %{public}u", reason);
3815ccb8f90Sopenharmony_ci        return;
3825ccb8f90Sopenharmony_ci    }
3835ccb8f90Sopenharmony_ci    if (stateMachine_ == nullptr) {
3845ccb8f90Sopenharmony_ci        return;
3855ccb8f90Sopenharmony_ci    }
3865ccb8f90Sopenharmony_ci
3875ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND,
3885ccb8f90Sopenharmony_ci        "Suspend when screen off, reason=%{public}d, action=%{public}u, "
3895ccb8f90Sopenharmony_ci        "delay=%{public}u, state=%{public}d, type=%{public}u",
3905ccb8f90Sopenharmony_ci        reason, action, delay, stateMachine_->GetState(), sleepType_);
3915ccb8f90Sopenharmony_ci    switch (stateMachine_->GetState()) {
3925ccb8f90Sopenharmony_ci        case PowerState::INACTIVE:
3935ccb8f90Sopenharmony_ci            StopSleep();
3945ccb8f90Sopenharmony_ci            StartSleepTimer(reason, action, delay);
3955ccb8f90Sopenharmony_ci            break;
3965ccb8f90Sopenharmony_ci        case PowerState::SLEEP:
3975ccb8f90Sopenharmony_ci            if (action != static_cast<uint32_t>(SuspendAction::ACTION_FORCE_SUSPEND)) {
3985ccb8f90Sopenharmony_ci                break;
3995ccb8f90Sopenharmony_ci            }
4005ccb8f90Sopenharmony_ci            if (sleepType_ == static_cast<uint32_t>(SuspendAction::ACTION_AUTO_SUSPEND)) {
4015ccb8f90Sopenharmony_ci                SystemSuspendController::GetInstance().Wakeup();
4025ccb8f90Sopenharmony_ci                StartSleepTimer(reason, action, 0);
4035ccb8f90Sopenharmony_ci            } else if (sleepType_ == static_cast<uint32_t>(SuspendAction::ACTION_FORCE_SUSPEND)) {
4045ccb8f90Sopenharmony_ci                if (stateMachine_->IsSwitchOpen()) {
4055ccb8f90Sopenharmony_ci                    POWER_HILOGI(FEATURE_SUSPEND, "switch off event is ignored.");
4065ccb8f90Sopenharmony_ci                    return;
4075ccb8f90Sopenharmony_ci                }
4085ccb8f90Sopenharmony_ci                SystemSuspendController::GetInstance().Wakeup();
4095ccb8f90Sopenharmony_ci                SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, true);
4105ccb8f90Sopenharmony_ci            } else {
4115ccb8f90Sopenharmony_ci                POWER_HILOGD(FEATURE_SUSPEND, "Nothing to do for no suspend");
4125ccb8f90Sopenharmony_ci            }
4135ccb8f90Sopenharmony_ci            break;
4145ccb8f90Sopenharmony_ci        default:
4155ccb8f90Sopenharmony_ci            break;
4165ccb8f90Sopenharmony_ci    }
4175ccb8f90Sopenharmony_ci}
4185ccb8f90Sopenharmony_ci
4195ccb8f90Sopenharmony_civoid SuspendController::ControlListener(SuspendDeviceType reason, uint32_t action, uint32_t delay)
4205ccb8f90Sopenharmony_ci{
4215ccb8f90Sopenharmony_ci    auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
4225ccb8f90Sopenharmony_ci    if (pms == nullptr) {
4235ccb8f90Sopenharmony_ci        return;
4245ccb8f90Sopenharmony_ci    }
4255ccb8f90Sopenharmony_ci    if (stateMachine_ == nullptr) {
4265ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "get PowerStateMachine instance error");
4275ccb8f90Sopenharmony_ci        return;
4285ccb8f90Sopenharmony_ci    }
4295ccb8f90Sopenharmony_ci
4305ccb8f90Sopenharmony_ci    if (pms->CheckDialogAndShuttingDown()) {
4315ccb8f90Sopenharmony_ci        return;
4325ccb8f90Sopenharmony_ci    }
4335ccb8f90Sopenharmony_ci
4345ccb8f90Sopenharmony_ci    bool isScreenOn = stateMachine_->IsScreenOn();
4355ccb8f90Sopenharmony_ci    if (!isScreenOn) {
4365ccb8f90Sopenharmony_ci        SuspendWhenScreenOff(reason, action, delay);
4375ccb8f90Sopenharmony_ci        return;
4385ccb8f90Sopenharmony_ci    }
4395ccb8f90Sopenharmony_ci
4405ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
4415ccb8f90Sopenharmony_ci    if (IsPowerOffInernalScreenOnlyScene(reason, static_cast<SuspendAction>(action), isScreenOn)) {
4425ccb8f90Sopenharmony_ci        ProcessPowerOffInternalScreenOnly(pms, reason);
4435ccb8f90Sopenharmony_ci        return;
4445ccb8f90Sopenharmony_ci    }
4455ccb8f90Sopenharmony_ci#endif
4465ccb8f90Sopenharmony_ci
4475ccb8f90Sopenharmony_ci    pid_t pid = IPCSkeleton::GetCallingPid();
4485ccb8f90Sopenharmony_ci    auto uid = IPCSkeleton::GetCallingUid();
4495ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND,
4505ccb8f90Sopenharmony_ci        "[UL_POWER] Try to suspend device, pid=%{public}d, uid=%{public}d, reason=%{public}d, action=%{public}u, "
4515ccb8f90Sopenharmony_ci        "delay=%{public}u",
4525ccb8f90Sopenharmony_ci        pid, uid, reason, action, delay);
4535ccb8f90Sopenharmony_ci    bool force = true;
4545ccb8f90Sopenharmony_ci    if (reason == SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT) {
4555ccb8f90Sopenharmony_ci        force = false;
4565ccb8f90Sopenharmony_ci    }
4575ccb8f90Sopenharmony_ci#ifdef HAS_HIVIEWDFX_HISYSEVENT_PART
4585ccb8f90Sopenharmony_ci    HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::POWER, "SLEEP_START",
4595ccb8f90Sopenharmony_ci        HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "TRIGGER_EVENT_TYPE", static_cast<int32_t>(reason),
4605ccb8f90Sopenharmony_ci        "ACTION_EVENT_TYPE", static_cast<int32_t>(force));
4615ccb8f90Sopenharmony_ci#endif
4625ccb8f90Sopenharmony_ci    bool ret = stateMachine_->SetState(
4635ccb8f90Sopenharmony_ci        PowerState::INACTIVE, stateMachine_->GetReasonBySuspendType(static_cast<SuspendDeviceType>(reason)), force);
4645ccb8f90Sopenharmony_ci    if (ret) {
4655ccb8f90Sopenharmony_ci        StartSleepTimer(reason, action, delay);
4665ccb8f90Sopenharmony_ci    }
4675ccb8f90Sopenharmony_ci}
4685ccb8f90Sopenharmony_ci
4695ccb8f90Sopenharmony_cistd::shared_ptr<SuspendMonitor> SuspendController::GetSpecifiedSuspendMonitor(SuspendDeviceType type) const
4705ccb8f90Sopenharmony_ci{
4715ccb8f90Sopenharmony_ci    auto iter = monitorMap_.find(type);
4725ccb8f90Sopenharmony_ci    if (iter == monitorMap_.end()) {
4735ccb8f90Sopenharmony_ci        return nullptr;
4745ccb8f90Sopenharmony_ci    }
4755ccb8f90Sopenharmony_ci    return iter->second;
4765ccb8f90Sopenharmony_ci}
4775ccb8f90Sopenharmony_ci
4785ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT
4795ccb8f90Sopenharmony_civoid SuspendController::PowerOffInternalScreen(SuspendDeviceType type)
4805ccb8f90Sopenharmony_ci{
4815ccb8f90Sopenharmony_ci    using namespace OHOS::Rosen;
4825ccb8f90Sopenharmony_ci    uint64_t screenId = DisplayManagerLite::GetInstance().GetInternalScreenId();
4835ccb8f90Sopenharmony_ci    bool ret = DisplayManagerLite::GetInstance().SetScreenPowerById(
4845ccb8f90Sopenharmony_ci        screenId, ScreenPowerState::POWER_OFF, PowerStateChangeReason::STATE_CHANGE_REASON_SWITCH);
4855ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND,
4865ccb8f90Sopenharmony_ci        "Power off internal screen, type = %{public}u, screenId = %{public}u, ret = %{public}d", type,
4875ccb8f90Sopenharmony_ci        static_cast<uint32_t>(screenId), ret);
4885ccb8f90Sopenharmony_ci}
4895ccb8f90Sopenharmony_ci
4905ccb8f90Sopenharmony_civoid SuspendController::PowerOffAllScreens(SuspendDeviceType type)
4915ccb8f90Sopenharmony_ci{
4925ccb8f90Sopenharmony_ci    using namespace OHOS::Rosen;
4935ccb8f90Sopenharmony_ci    bool ret = ScreenManagerLite::GetInstance().SetScreenPowerForAll(
4945ccb8f90Sopenharmony_ci        ScreenPowerState::POWER_OFF, PowerStateChangeReason::STATE_CHANGE_REASON_SWITCH);
4955ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND, "Power off all screens, type = %{public}u, ret = %{public}d", type, ret);
4965ccb8f90Sopenharmony_ci}
4975ccb8f90Sopenharmony_ci
4985ccb8f90Sopenharmony_cibool SuspendController::IsPowerOffInernalScreenOnlyScene(
4995ccb8f90Sopenharmony_ci    SuspendDeviceType reason, SuspendAction action, bool isScreenOn) const
5005ccb8f90Sopenharmony_ci{
5015ccb8f90Sopenharmony_ci    if (reason == SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH && isScreenOn &&
5025ccb8f90Sopenharmony_ci        action == SuspendAction::ACTION_NONE && stateMachine_->GetExternalScreenNumber() > 0) {
5035ccb8f90Sopenharmony_ci        return true;
5045ccb8f90Sopenharmony_ci    }
5055ccb8f90Sopenharmony_ci    return false;
5065ccb8f90Sopenharmony_ci}
5075ccb8f90Sopenharmony_ci
5085ccb8f90Sopenharmony_civoid SuspendController::ProcessPowerOffInternalScreenOnly(const sptr<PowerMgrService>& pms, SuspendDeviceType reason)
5095ccb8f90Sopenharmony_ci{
5105ccb8f90Sopenharmony_ci    POWER_HILOGI(
5115ccb8f90Sopenharmony_ci        FEATURE_SUSPEND, "[UL_POWER] Power off internal screen when closing switch is configured as no operation");
5125ccb8f90Sopenharmony_ci    PowerOffInternalScreen(reason);
5135ccb8f90Sopenharmony_ci    pms->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_SWITCH, false);
5145ccb8f90Sopenharmony_ci}
5155ccb8f90Sopenharmony_ci#endif
5165ccb8f90Sopenharmony_ci
5175ccb8f90Sopenharmony_civoid SuspendController::StartSleepTimer(SuspendDeviceType reason, uint32_t action, uint32_t delay)
5185ccb8f90Sopenharmony_ci{
5195ccb8f90Sopenharmony_ci    if (static_cast<SuspendAction>(action) == SuspendAction::ACTION_AUTO_SUSPEND) {
5205ccb8f90Sopenharmony_ci        if (stateMachine_->GetSleepTime() < 0) {
5215ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND, "sleeptime less than zero, no need suspend");
5225ccb8f90Sopenharmony_ci            return;
5235ccb8f90Sopenharmony_ci        }
5245ccb8f90Sopenharmony_ci    }
5255ccb8f90Sopenharmony_ci
5265ccb8f90Sopenharmony_ci    int64_t tick = GetTickCount();
5275ccb8f90Sopenharmony_ci    int64_t timeout = tick + static_cast<int64_t>(delay);
5285ccb8f90Sopenharmony_ci    if (timeout < tick) {
5295ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "Sleep timer overflow with tick = %{public}s, delay = %{public}u",
5305ccb8f90Sopenharmony_ci            std::to_string(tick).c_str(), delay);
5315ccb8f90Sopenharmony_ci        return;
5325ccb8f90Sopenharmony_ci    }
5335ccb8f90Sopenharmony_ci
5345ccb8f90Sopenharmony_ci    ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
5355ccb8f90Sopenharmony_ci    if ((timeout > sleepTime_) && (sleepTime_ != -1)) {
5365ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "already have a sleep event (%{public}" PRId64 " > %{public}" PRId64 ")", timeout,
5375ccb8f90Sopenharmony_ci            sleepTime_);
5385ccb8f90Sopenharmony_ci        ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
5395ccb8f90Sopenharmony_ci        return;
5405ccb8f90Sopenharmony_ci    }
5415ccb8f90Sopenharmony_ci    sleepTime_ = timeout;
5425ccb8f90Sopenharmony_ci    sleepReason_ = reason;
5435ccb8f90Sopenharmony_ci    sleepAction_ = action;
5445ccb8f90Sopenharmony_ci    sleepDuration_ = delay;
5455ccb8f90Sopenharmony_ci    sleepType_ = action;
5465ccb8f90Sopenharmony_ci    FFRTTask task = [this, reason, action] {
5475ccb8f90Sopenharmony_ci        HandleAction(reason, action);
5485ccb8f90Sopenharmony_ci    };
5495ccb8f90Sopenharmony_ci
5505ccb8f90Sopenharmony_ci    if (ffrtTimer_ != nullptr) {
5515ccb8f90Sopenharmony_ci        ffrtTimer_->SetTimer(TIMER_ID_SLEEP, task, delay);
5525ccb8f90Sopenharmony_ci    } else {
5535ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}u) failed, timer is null", __func__, delay);
5545ccb8f90Sopenharmony_ci    }
5555ccb8f90Sopenharmony_ci    ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
5565ccb8f90Sopenharmony_ci}
5575ccb8f90Sopenharmony_ci
5585ccb8f90Sopenharmony_civoid SuspendController::HandleAction(SuspendDeviceType reason, uint32_t action)
5595ccb8f90Sopenharmony_ci{
5605ccb8f90Sopenharmony_ci    switch (static_cast<SuspendAction>(action)) {
5615ccb8f90Sopenharmony_ci        case SuspendAction::ACTION_AUTO_SUSPEND:
5625ccb8f90Sopenharmony_ci            HandleAutoSleep(reason);
5635ccb8f90Sopenharmony_ci            break;
5645ccb8f90Sopenharmony_ci        case SuspendAction::ACTION_FORCE_SUSPEND:
5655ccb8f90Sopenharmony_ci            HandleForceSleep(reason);
5665ccb8f90Sopenharmony_ci            break;
5675ccb8f90Sopenharmony_ci        case SuspendAction::ACTION_HIBERNATE:
5685ccb8f90Sopenharmony_ci            HandleHibernate(reason);
5695ccb8f90Sopenharmony_ci            break;
5705ccb8f90Sopenharmony_ci        case SuspendAction::ACTION_SHUTDOWN:
5715ccb8f90Sopenharmony_ci            HandleShutdown(reason);
5725ccb8f90Sopenharmony_ci            break;
5735ccb8f90Sopenharmony_ci        case SuspendAction::ACTION_NONE:
5745ccb8f90Sopenharmony_ci        default:
5755ccb8f90Sopenharmony_ci            break;
5765ccb8f90Sopenharmony_ci    }
5775ccb8f90Sopenharmony_ci    ffrtMutexMap_.Lock(TIMER_ID_SLEEP);
5785ccb8f90Sopenharmony_ci    sleepTime_ = -1;
5795ccb8f90Sopenharmony_ci    sleepAction_ = static_cast<uint32_t>(SuspendAction::ACTION_NONE);
5805ccb8f90Sopenharmony_ci    ffrtMutexMap_.Unlock(TIMER_ID_SLEEP);
5815ccb8f90Sopenharmony_ci}
5825ccb8f90Sopenharmony_ci
5835ccb8f90Sopenharmony_civoid SuspendController::HandleAutoSleep(SuspendDeviceType reason)
5845ccb8f90Sopenharmony_ci{
5855ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND, "auto suspend by reason=%{public}d", reason);
5865ccb8f90Sopenharmony_ci
5875ccb8f90Sopenharmony_ci    if (stateMachine_ == nullptr) {
5885ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
5895ccb8f90Sopenharmony_ci        return;
5905ccb8f90Sopenharmony_ci    }
5915ccb8f90Sopenharmony_ci    bool ret = stateMachine_->SetState(
5925ccb8f90Sopenharmony_ci        PowerState::SLEEP, stateMachine_->GetReasonBySuspendType(reason));
5935ccb8f90Sopenharmony_ci    if (ret) {
5945ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "State changed, set sleep timer");
5955ccb8f90Sopenharmony_ci        TriggerSyncSleepCallback(false);
5965ccb8f90Sopenharmony_ci        SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, false);
5975ccb8f90Sopenharmony_ci    } else {
5985ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "auto suspend: State change failed");
5995ccb8f90Sopenharmony_ci    }
6005ccb8f90Sopenharmony_ci}
6015ccb8f90Sopenharmony_ci
6025ccb8f90Sopenharmony_civoid SuspendController::HandleForceSleep(SuspendDeviceType reason)
6035ccb8f90Sopenharmony_ci{
6045ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND, "force suspend by reason=%{public}d", reason);
6055ccb8f90Sopenharmony_ci    if (stateMachine_ == nullptr) {
6065ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
6075ccb8f90Sopenharmony_ci        return;
6085ccb8f90Sopenharmony_ci    }
6095ccb8f90Sopenharmony_ci
6105ccb8f90Sopenharmony_ci#ifdef POWER_MANAGER_ENABLE_FORCE_SLEEP_BROADCAST
6115ccb8f90Sopenharmony_ci    auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
6125ccb8f90Sopenharmony_ci    if (pms != nullptr && pms->GetSuspendController() != nullptr) {
6135ccb8f90Sopenharmony_ci        pms->GetSuspendController()->SetForceSleepingFlag(true);
6145ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "Set flag of force sleeping to true");
6155ccb8f90Sopenharmony_ci    } else {
6165ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "Failed to set flag of force sleeping, pms or suspendController is nullptr");
6175ccb8f90Sopenharmony_ci    }
6185ccb8f90Sopenharmony_ci#endif
6195ccb8f90Sopenharmony_ci    bool ret = stateMachine_->SetState(PowerState::SLEEP,
6205ccb8f90Sopenharmony_ci        stateMachine_->GetReasonBySuspendType(reason), true);
6215ccb8f90Sopenharmony_ci    if (ret) {
6225ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "State changed, system suspend");
6235ccb8f90Sopenharmony_ci        onForceSleep = true;
6245ccb8f90Sopenharmony_ci        TriggerSyncSleepCallback(false);
6255ccb8f90Sopenharmony_ci
6265ccb8f90Sopenharmony_ci        FFRTTask task = [this, reason] {
6275ccb8f90Sopenharmony_ci            SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, true);
6285ccb8f90Sopenharmony_ci        };
6295ccb8f90Sopenharmony_ci        if (ffrtTimer_ != nullptr) {
6305ccb8f90Sopenharmony_ci            ffrtTimer_->SetTimer(TIMER_ID_SLEEP, task, FORCE_SLEEP_DELAY_MS);
6315ccb8f90Sopenharmony_ci        } else {
6325ccb8f90Sopenharmony_ci            POWER_HILOGE(FEATURE_SUSPEND, "%{public}s: SetTimer(%{public}d) failed, timer is null",
6335ccb8f90Sopenharmony_ci                __func__, FORCE_SLEEP_DELAY_MS);
6345ccb8f90Sopenharmony_ci        }
6355ccb8f90Sopenharmony_ci    } else {
6365ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "force suspend: State change failed");
6375ccb8f90Sopenharmony_ci    }
6385ccb8f90Sopenharmony_ci}
6395ccb8f90Sopenharmony_ci
6405ccb8f90Sopenharmony_civoid SuspendController::HandleHibernate(SuspendDeviceType reason)
6415ccb8f90Sopenharmony_ci{
6425ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND, "force suspend by reason=%{public}d", reason);
6435ccb8f90Sopenharmony_ci    if (stateMachine_ == nullptr) {
6445ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
6455ccb8f90Sopenharmony_ci        return;
6465ccb8f90Sopenharmony_ci    }
6475ccb8f90Sopenharmony_ci    bool ret = stateMachine_->SetState(
6485ccb8f90Sopenharmony_ci        PowerState::HIBERNATE, stateMachine_->GetReasonBySuspendType(reason), true);
6495ccb8f90Sopenharmony_ci    if (ret) {
6505ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "State changed, call hibernate");
6515ccb8f90Sopenharmony_ci    } else {
6525ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "Hibernate: State change failed");
6535ccb8f90Sopenharmony_ci    }
6545ccb8f90Sopenharmony_ci}
6555ccb8f90Sopenharmony_ci
6565ccb8f90Sopenharmony_civoid SuspendController::HandleShutdown(SuspendDeviceType reason)
6575ccb8f90Sopenharmony_ci{
6585ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND, "shutdown by reason=%{public}d", reason);
6595ccb8f90Sopenharmony_ci    shutdownController_->Shutdown(std::to_string(static_cast<uint32_t>(reason)));
6605ccb8f90Sopenharmony_ci}
6615ccb8f90Sopenharmony_ci
6625ccb8f90Sopenharmony_civoid SuspendController::Reset()
6635ccb8f90Sopenharmony_ci{
6645ccb8f90Sopenharmony_ci    ffrtTimer_.reset();
6655ccb8f90Sopenharmony_ci}
6665ccb8f90Sopenharmony_ci
6675ccb8f90Sopenharmony_ciconst std::shared_ptr<SuspendMonitor> SuspendMonitor::CreateMonitor(SuspendSource& source)
6685ccb8f90Sopenharmony_ci{
6695ccb8f90Sopenharmony_ci    SuspendDeviceType reason = source.GetReason();
6705ccb8f90Sopenharmony_ci    std::shared_ptr<SuspendMonitor> monitor = nullptr;
6715ccb8f90Sopenharmony_ci    switch (reason) {
6725ccb8f90Sopenharmony_ci        case SuspendDeviceType::SUSPEND_DEVICE_REASON_POWER_KEY:
6735ccb8f90Sopenharmony_ci            monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<PowerKeySuspendMonitor>(source));
6745ccb8f90Sopenharmony_ci            break;
6755ccb8f90Sopenharmony_ci        case SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT:
6765ccb8f90Sopenharmony_ci            monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<TimeoutSuspendMonitor>(source));
6775ccb8f90Sopenharmony_ci            break;
6785ccb8f90Sopenharmony_ci        case SuspendDeviceType::SUSPEND_DEVICE_REASON_LID:
6795ccb8f90Sopenharmony_ci            monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<LidSuspendMonitor>(source));
6805ccb8f90Sopenharmony_ci            break;
6815ccb8f90Sopenharmony_ci        case SuspendDeviceType::SUSPEND_DEVICE_REASON_SWITCH:
6825ccb8f90Sopenharmony_ci            monitor = std::static_pointer_cast<SuspendMonitor>(std::make_shared<SwitchSuspendMonitor>(source));
6835ccb8f90Sopenharmony_ci            break;
6845ccb8f90Sopenharmony_ci        default:
6855ccb8f90Sopenharmony_ci            POWER_HILOGE(FEATURE_SUSPEND, "CreateMonitor : Invalid reason=%{public}d", reason);
6865ccb8f90Sopenharmony_ci            break;
6875ccb8f90Sopenharmony_ci    }
6885ccb8f90Sopenharmony_ci    return monitor;
6895ccb8f90Sopenharmony_ci}
6905ccb8f90Sopenharmony_ci
6915ccb8f90Sopenharmony_ci/** PowerKeySuspendMonitor Implement */
6925ccb8f90Sopenharmony_cibool PowerKeySuspendMonitor::Init()
6935ccb8f90Sopenharmony_ci{
6945ccb8f90Sopenharmony_ci#ifdef HAS_MULTIMODALINPUT_INPUT_PART
6955ccb8f90Sopenharmony_ci    if (powerkeyReleaseId_ >= 0) {
6965ccb8f90Sopenharmony_ci        return true;
6975ccb8f90Sopenharmony_ci    }
6985ccb8f90Sopenharmony_ci    std::shared_ptr<OHOS::MMI::KeyOption> keyOption = std::make_shared<OHOS::MMI::KeyOption>();
6995ccb8f90Sopenharmony_ci    std::set<int32_t> preKeys;
7005ccb8f90Sopenharmony_ci
7015ccb8f90Sopenharmony_ci    keyOption.reset();
7025ccb8f90Sopenharmony_ci    keyOption = std::make_shared<OHOS::MMI::KeyOption>();
7035ccb8f90Sopenharmony_ci    keyOption->SetPreKeys(preKeys);
7045ccb8f90Sopenharmony_ci    keyOption->SetFinalKey(OHOS::MMI::KeyEvent::KEYCODE_POWER);
7055ccb8f90Sopenharmony_ci    keyOption->SetFinalKeyDown(false);
7065ccb8f90Sopenharmony_ci    keyOption->SetFinalKeyDownDuration(0);
7075ccb8f90Sopenharmony_ci    powerkeyReleaseId_ = InputManager::GetInstance()->SubscribeKeyEvent(
7085ccb8f90Sopenharmony_ci        keyOption, [this](std::shared_ptr<OHOS::MMI::KeyEvent> keyEvent) {
7095ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER] Received powerkey up");
7105ccb8f90Sopenharmony_ci
7115ccb8f90Sopenharmony_ci            static int64_t lastPowerkeyUpTime = 0;
7125ccb8f90Sopenharmony_ci            int64_t currTime = GetTickCount();
7135ccb8f90Sopenharmony_ci            if (lastPowerkeyUpTime != 0 && currTime - lastPowerkeyUpTime < POWERKEY_MIN_INTERVAL) {
7145ccb8f90Sopenharmony_ci                POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Last powerkey up within 350ms, skip. "
7155ccb8f90Sopenharmony_ci                    "%{public}" PRId64 ", %{public}" PRId64, currTime, lastPowerkeyUpTime);
7165ccb8f90Sopenharmony_ci                return;
7175ccb8f90Sopenharmony_ci            }
7185ccb8f90Sopenharmony_ci            lastPowerkeyUpTime = currTime;
7195ccb8f90Sopenharmony_ci
7205ccb8f90Sopenharmony_ci            auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
7215ccb8f90Sopenharmony_ci            if (pms == nullptr) {
7225ccb8f90Sopenharmony_ci                return;
7235ccb8f90Sopenharmony_ci            }
7245ccb8f90Sopenharmony_ci            std::shared_ptr<SuspendController> suspendController = pms->GetSuspendController();
7255ccb8f90Sopenharmony_ci            if (suspendController->GetPowerkeyDownWhenScreenOff()) {
7265ccb8f90Sopenharmony_ci                POWER_HILOGI(FEATURE_SUSPEND,
7275ccb8f90Sopenharmony_ci                    "[UL_POWER] The powerkey was pressed when screenoff, ignore this powerkey up event.");
7285ccb8f90Sopenharmony_ci                return;
7295ccb8f90Sopenharmony_ci            }
7305ccb8f90Sopenharmony_ci            auto powerkeyScreenOffTask = [*this]() mutable {
7315ccb8f90Sopenharmony_ci                Notify();
7325ccb8f90Sopenharmony_ci                powerkeyScreenOff_ = false;
7335ccb8f90Sopenharmony_ci                EndPowerkeyScreenOff();
7345ccb8f90Sopenharmony_ci            };
7355ccb8f90Sopenharmony_ci            BeginPowerkeyScreenOff();
7365ccb8f90Sopenharmony_ci            powerkeyScreenOff_ = true;
7375ccb8f90Sopenharmony_ci            ffrt::submit(powerkeyScreenOffTask, {}, {&powerkeyScreenOff_});
7385ccb8f90Sopenharmony_ci            POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER]submitted screen off ffrt task");
7395ccb8f90Sopenharmony_ci        });
7405ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_SUSPEND, "powerkeyReleaseId_=%{public}d", powerkeyReleaseId_);
7415ccb8f90Sopenharmony_ci    return powerkeyReleaseId_ >= 0 ? true : false;
7425ccb8f90Sopenharmony_ci#else
7435ccb8f90Sopenharmony_ci    return false;
7445ccb8f90Sopenharmony_ci#endif
7455ccb8f90Sopenharmony_ci}
7465ccb8f90Sopenharmony_ci
7475ccb8f90Sopenharmony_civoid PowerKeySuspendMonitor::BeginPowerkeyScreenOff() const
7485ccb8f90Sopenharmony_ci{
7495ccb8f90Sopenharmony_ci    auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
7505ccb8f90Sopenharmony_ci    if (pms == nullptr) {
7515ccb8f90Sopenharmony_ci        return;
7525ccb8f90Sopenharmony_ci    }
7535ccb8f90Sopenharmony_ci    auto stateMachine = pms->GetPowerStateMachine();
7545ccb8f90Sopenharmony_ci    if (stateMachine == nullptr) {
7555ccb8f90Sopenharmony_ci        return;
7565ccb8f90Sopenharmony_ci    }
7575ccb8f90Sopenharmony_ci    auto stateAction = stateMachine->GetStateAction();
7585ccb8f90Sopenharmony_ci    if (stateAction == nullptr) {
7595ccb8f90Sopenharmony_ci        return;
7605ccb8f90Sopenharmony_ci    }
7615ccb8f90Sopenharmony_ci    stateAction->BeginPowerkeyScreenOff();
7625ccb8f90Sopenharmony_ci}
7635ccb8f90Sopenharmony_ci
7645ccb8f90Sopenharmony_civoid PowerKeySuspendMonitor::EndPowerkeyScreenOff() const
7655ccb8f90Sopenharmony_ci{
7665ccb8f90Sopenharmony_ci    auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
7675ccb8f90Sopenharmony_ci    if (pms == nullptr) {
7685ccb8f90Sopenharmony_ci        return;
7695ccb8f90Sopenharmony_ci    }
7705ccb8f90Sopenharmony_ci    auto stateMachine = pms->GetPowerStateMachine();
7715ccb8f90Sopenharmony_ci    if (stateMachine == nullptr) {
7725ccb8f90Sopenharmony_ci        return;
7735ccb8f90Sopenharmony_ci    }
7745ccb8f90Sopenharmony_ci    auto stateAction = stateMachine->GetStateAction();
7755ccb8f90Sopenharmony_ci    if (stateAction == nullptr) {
7765ccb8f90Sopenharmony_ci        return;
7775ccb8f90Sopenharmony_ci    }
7785ccb8f90Sopenharmony_ci    stateAction->EndPowerkeyScreenOff();
7795ccb8f90Sopenharmony_ci}
7805ccb8f90Sopenharmony_ci
7815ccb8f90Sopenharmony_civoid PowerKeySuspendMonitor::Cancel()
7825ccb8f90Sopenharmony_ci{
7835ccb8f90Sopenharmony_ci#ifdef HAS_MULTIMODALINPUT_INPUT_PART
7845ccb8f90Sopenharmony_ci    if (powerkeyReleaseId_ >= 0) {
7855ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_SUSPEND, "UnsubscribeKeyEvent: PowerKeySuspendMonitor");
7865ccb8f90Sopenharmony_ci        InputManager::GetInstance()->UnsubscribeKeyEvent(powerkeyReleaseId_);
7875ccb8f90Sopenharmony_ci        powerkeyReleaseId_ = -1;
7885ccb8f90Sopenharmony_ci    }
7895ccb8f90Sopenharmony_ci#endif
7905ccb8f90Sopenharmony_ci}
7915ccb8f90Sopenharmony_ci
7925ccb8f90Sopenharmony_ci/** Timeout Implement */
7935ccb8f90Sopenharmony_cibool TimeoutSuspendMonitor::Init()
7945ccb8f90Sopenharmony_ci{
7955ccb8f90Sopenharmony_ci    return true;
7965ccb8f90Sopenharmony_ci}
7975ccb8f90Sopenharmony_ci
7985ccb8f90Sopenharmony_civoid TimeoutSuspendMonitor::Cancel() {}
7995ccb8f90Sopenharmony_ci
8005ccb8f90Sopenharmony_civoid TimeoutSuspendMonitor::HandleEvent()
8015ccb8f90Sopenharmony_ci{
8025ccb8f90Sopenharmony_ci    POWER_HILOGI(FEATURE_INPUT, "TimeoutSuspendMonitor HandleEvent.");
8035ccb8f90Sopenharmony_ci    Notify();
8045ccb8f90Sopenharmony_ci}
8055ccb8f90Sopenharmony_ci
8065ccb8f90Sopenharmony_ci/** LidSuspendMonitor Implement */
8075ccb8f90Sopenharmony_ci
8085ccb8f90Sopenharmony_cibool LidSuspendMonitor::Init()
8095ccb8f90Sopenharmony_ci{
8105ccb8f90Sopenharmony_ci    return true;
8115ccb8f90Sopenharmony_ci}
8125ccb8f90Sopenharmony_ci
8135ccb8f90Sopenharmony_civoid LidSuspendMonitor::Cancel() {}
8145ccb8f90Sopenharmony_ci
8155ccb8f90Sopenharmony_ci/** SwitchSuspendMonitor Implement */
8165ccb8f90Sopenharmony_ci
8175ccb8f90Sopenharmony_cibool SwitchSuspendMonitor::Init()
8185ccb8f90Sopenharmony_ci{
8195ccb8f90Sopenharmony_ci    return true;
8205ccb8f90Sopenharmony_ci}
8215ccb8f90Sopenharmony_ci
8225ccb8f90Sopenharmony_civoid SwitchSuspendMonitor::Cancel() {}
8235ccb8f90Sopenharmony_ci} // namespace PowerMgr
8245ccb8f90Sopenharmony_ci} // namespace OHOS
825