/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef POWERMGR_POWER_STATE_MACHINE_H #define POWERMGR_POWER_STATE_MACHINE_H #include #include #include #include "actions/idevice_state_action.h" #include "ffrt_utils.h" #include "ipower_state_callback.h" #include "power_common.h" #include "power_state_machine_info.h" #include "running_lock_info.h" #ifdef POWER_MANAGER_POWER_ENABLE_S4 #include "hibernate_controller.h" #endif #define DEFAULT_DISPLAY_OFF_TIME 30000 #define DEFAULT_SLEEP_TIME 5000 namespace OHOS { namespace PowerMgr { class RunningLockMgr; class PowerMgrService; struct ScreenState { DisplayState state; int64_t lastOnTime; int64_t lastOffTime; }; struct DevicePowerState { ScreenState screenState; // record the last time when get wakeup event from A side int64_t lastWakeupEventTime; // record the last time when calling func RefreshActivityInner int64_t lastRefreshActivityTime; // record the last time when calling func WakeupDeviceInner int64_t lastWakeupDeviceTime; // record the last time when calling func SuspendDeviceInner int64_t lastSuspendDeviceTime; }; enum class TransitResult { SUCCESS = 0, ALREADY_IN_STATE = 1, LOCKING = 2, HDI_ERR = 3, DISPLAY_ON_ERR = 4, DISPLAY_OFF_ERR = 5, FORBID_TRANSIT = 6, PRE_BRIGHT_ERR = 7, OTHER_ERR = 99 }; class PowerStateMachine : public std::enable_shared_from_this { public: explicit PowerStateMachine(const wptr& pms); ~PowerStateMachine(); enum { CHECK_USER_ACTIVITY_TIMEOUT_MSG = 0, CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG, CHECK_PRE_BRIGHT_AUTH_TIMEOUT_MSG, CHECK_PROXIMITY_SCREEN_OFF_MSG, }; static void onSuspend(); static void onWakeup(); bool Init(); void InitState(); void SuspendDeviceInner( pid_t pid, int64_t callTimeMs, SuspendDeviceType type, bool suspendImmed, bool ignoreScreenState = false); void WakeupDeviceInner( pid_t pid, int64_t callTimeMs, WakeupDeviceType type, const std::string& details, const std::string& pkgName); void HandlePreBrightWakeUp(int64_t callTimeMs, WakeupDeviceType type, const std::string& details, const std::string& pkgName, bool timeoutTriggered = false); void RefreshActivityInner(pid_t pid, int64_t callTimeMs, UserActivityType type, bool needChangeBacklight); bool CheckRefreshTime(); bool OverrideScreenOffTimeInner(int64_t timeout); bool RestoreScreenOffTimeInner(); void ReceiveScreenEvent(bool isScreenOn); bool IsScreenOn(bool needPrintLog = true); bool IsFoldScreenOn(); bool IsCollaborationScreenOn(); void Reset(); int64_t GetSleepTime(); #ifdef MSDP_MOVEMENT_ENABLE bool IsMovementStateOn(); #endif PowerState GetState() { return currentState_; }; const std::shared_ptr& GetStateAction() { return stateAction_; }; bool ForceSuspendDeviceInner(pid_t pid, int64_t callTimeMs); #ifdef POWER_MANAGER_POWER_ENABLE_S4 bool HibernateInner(bool clearMemory); #endif void RegisterPowerStateCallback(const sptr& callback, bool isSync = true); void UnRegisterPowerStateCallback(const sptr& callback); void SetDelayTimer(int64_t delayTime, int32_t event); void CancelDelayTimer(int32_t event); void ResetInactiveTimer(bool needPrintLog = true); void ResetSleepTimer(); void SetAutoSuspend(SuspendDeviceType type, uint32_t delay); bool SetState(PowerState state, StateChangeReason reason, bool force = false); bool TryToCancelScreenOff(); void BeginPowerkeyScreenOff(); void EndPowerkeyScreenOff(); void SetDisplaySuspend(bool enable); StateChangeReason GetReasonByUserActivity(UserActivityType type); StateChangeReason GetReasonByWakeType(WakeupDeviceType type); StateChangeReason GetReasionBySuspendType(SuspendDeviceType type); WakeupDeviceType ParseWakeupDeviceType(const std::string& details); static void DisplayOffTimeUpdateFunc(); // only use for test int64_t GetLastSuspendDeviceTime() const { return mDeviceState_.lastSuspendDeviceTime; } int64_t GetLastWakeupDeviceTime() const { return mDeviceState_.lastWakeupDeviceTime; } int64_t GetLastRefreshActivityTime() const { return mDeviceState_.lastRefreshActivityTime; } int64_t GetLastWakeupEventTime() const { return mDeviceState_.lastWakeupEventTime; } void SetSwitchState(bool switchOpen) { switchOpen_ = switchOpen; } bool IsSwitchOpen() const { return switchOpen_; } #ifdef POWER_MANAGER_POWER_ENABLE_S4 bool IsHibernating() const { return hibernating_; } #endif int64_t GetLastOnTime() const { return mDeviceState_.screenState.lastOnTime; } class PowerStateCallbackDeathRecipient : public IRemoteObject::DeathRecipient { public: PowerStateCallbackDeathRecipient() = default; virtual void OnRemoteDied(const wptr& remote); virtual ~PowerStateCallbackDeathRecipient() = default; }; void DumpInfo(std::string& result); void EnableMock(IDeviceStateAction* mockAction); int64_t GetDisplayOffTime(); int64_t GetDimTime(int64_t displayOffTime); static constexpr int64_t OFF_TIMEOUT_FACTOR = 5; static constexpr int64_t MAX_DIM_TIME_MS = 7500; static constexpr int64_t COORDINATED_STATE_SCREEN_OFF_TIME_MS = 10000; static constexpr uint32_t SCREEN_CHANGE_TIMEOUT_MS = 10000; static constexpr uint32_t SCREEN_CHANGE_REPORT_INTERVAL_MS = 600000; void SetDisplayOffTime(int64_t time, bool needUpdateSetting = true); static void RegisterDisplayOffTimeObserver(); static void UnregisterDisplayOffTimeObserver(); void SetSleepTime(int64_t time); bool IsRunningLockEnabled(RunningLockType type); void SetForceTimingOut(bool enabled); void LockScreenAfterTimingOut(bool enabled, bool checkScreenOnLock, bool sendScreenOffEvent); bool IsSettingState(PowerState state); private: enum PreBrightState : uint32_t { PRE_BRIGHT_UNSTART = 0, PRE_BRIGHT_STARTED, PRE_BRIGHT_FINISHED, }; class SettingStateFlag { public: SettingStateFlag(PowerState state, std::shared_ptr owner, StateChangeReason reason) : owner_(owner) { std::shared_ptr stateMachine = owner_.lock(); int64_t flag; if (state == PowerState::DIM && reason == StateChangeReason::STATE_CHANGE_REASON_COORDINATION) { flag = static_cast(StateFlag::FORCE_SETTING_DIM); } else { flag = static_cast(state); } stateMachine->settingStateFlag_ = flag; } SettingStateFlag(const SettingStateFlag&) = delete; SettingStateFlag& operator=(const SettingStateFlag&) = delete; SettingStateFlag(SettingStateFlag&&) = delete; SettingStateFlag& operator=(SettingStateFlag&&) = delete; ~SettingStateFlag() { std::shared_ptr stateMachine = owner_.lock(); stateMachine->settingStateFlag_ = static_cast(StateFlag::NONE); } enum class StateFlag : int64_t { FORCE_SETTING_DIM = -3, SETTING_DIM_INTERRUPTED = -2, NONE = -1 }; protected: std::weak_ptr owner_; }; class StateController { public: StateController(PowerState state, std::shared_ptr owner, std::function action) : state_(state), owner_(owner), action_(action) { } ~StateController() = default; PowerState GetState() { return state_; } TransitResult TransitTo(StateChangeReason reason, bool ignoreLock = false); void RecordFailure(PowerState from, StateChangeReason trigger, TransitResult failReason); static bool IsReallyFailed(StateChangeReason reason); StateChangeReason lastReason_; int64_t lastTime_ {0}; PowerState failFrom_; StateChangeReason failTrigger_; std::string failReason_; int64_t failTime_ {0}; protected: bool CheckState(); bool NeedNotify(PowerState currentState); void MatchState(PowerState& currentState, DisplayState state); void CorrectState(PowerState& currentState, PowerState correctState, DisplayState state); PowerState state_; std::weak_ptr owner_; std::function action_; }; struct classcomp { bool operator()(const sptr& l, const sptr& r) const { return l->AsObject() < r->AsObject(); } }; class ScreenChangeCheck { public: ScreenChangeCheck(std::shared_ptr ffrtTimer, PowerState state, StateChangeReason reason); ~ScreenChangeCheck() noexcept; void SetReportTimerStartFlag(bool flag) const; void ReportSysEvent(const std::string& msg) const; private: pid_t pid_ {-1}; pid_t uid_ {-1}; mutable bool isReportTimerStarted_ {false}; std::shared_ptr ffrtTimer_ {nullptr}; PowerState state_; StateChangeReason reason_; }; static std::string GetTransitResultString(TransitResult result); void UpdateSettingStateFlag(PowerState state, StateChangeReason reason); void RestoreSettingStateFlag(); void InitStateMap(); void EmplaceAwake(); void EmplaceFreeze(); void EmplaceInactive(); void EmplaceStandBy(); void EmplaceDoze(); void EmplaceSleep(); void EmplaceHibernate(); void EmplaceShutdown(); void EmplaceDim(); void InitTransitMap(); bool CanTransitTo(PowerState to, StateChangeReason reason); void NotifyPowerStateChanged(PowerState state, StateChangeReason reason = StateChangeReason::STATE_CHANGE_REASON_APPLICATION); void SendEventToPowerMgrNotify(PowerState state, int64_t callTime); bool CheckRunningLock(PowerState state); void HandleActivityTimeout(); void HandleActivitySleepTimeout(); void HandleSystemWakeup(); void AppendDumpInfo(std::string& result, std::string& reason, std::string& time); std::shared_ptr GetStateController(PowerState state); void ResetScreenOffPreTimeForSwing(int64_t displayOffTime); void ShowCurrentScreenLocks(); void HandleProximityScreenOffTimer(PowerState state, StateChangeReason reason); bool HandlePreBrightState(StateChangeReason reason); bool IsPreBrightAuthReason(StateChangeReason reason); bool IsPreBrightWakeUp(WakeupDeviceType type); bool NeedShowScreenLocks(PowerState state); #ifdef POWER_MANAGER_POWER_ENABLE_S4 bool PrepareHibernate(bool clearMemory); #endif #ifdef HAS_SENSORS_SENSOR_PART bool IsProximityClose(); #endif std::shared_ptr ffrtTimer_ {nullptr}; const wptr pms_; PowerState currentState_; std::map>> lockMap_; std::map> controllerMap_; std::mutex mutex_; // all change to currentState_ should be inside stateMutex_ std::mutex stateMutex_; DevicePowerState mDeviceState_; sptr powerStateCBDeathRecipient_; std::set, classcomp> syncPowerStateListeners_; std::set, classcomp> asyncPowerStateListeners_; std::shared_ptr stateAction_; std::atomic displayOffTime_ {DEFAULT_DISPLAY_OFF_TIME}; int64_t sleepTime_ {DEFAULT_SLEEP_TIME}; bool enableDisplaySuspend_ {false}; bool isScreenOffTimeOverride_ {false}; std::unordered_map> forbidMap_; std::atomic switchOpen_ {true}; #ifdef POWER_MANAGER_POWER_ENABLE_S4 std::atomic hibernating_ {false}; #endif std::unordered_map>> allowMapByReason_; std::atomic forceTimingOut_ {false}; std::atomic enabledTimingOutLockScreen_ {true}; std::atomic enabledTimingOutLockScreenCheckLock_ {false}; std::atomic enabledScreenOffEvent_{true}; std::atomic settingStateFlag_ {-1}; std::atomic settingOnStateFlag_ {false}; std::atomic settingOffStateFlag_ {false}; std::atomic isAwakeNotified_ {false}; std::atomic preBrightState_ {PRE_BRIGHT_UNSTART}; std::atomic proximityScreenOffTimerStarted_ {false}; }; } // namespace PowerMgr } // namespace OHOS #endif // POWERMGR_POWER_STATE_MACHINE_H