From c16220e242f1bea2669011f82853fe70098d45e0 Mon Sep 17 00:00:00 2001 From: wangyantian Date: Mon, 26 May 2025 19:19:05 +0800 Subject: [PATCH] fix: fix screen not turned on caused by superfast switch open/close event Signed-off-by: wangyantian --- services/native/include/power_state_machine.h | 8 ++- services/native/src/power_state_machine.cpp | 50 ++++++++++++++----- .../native/src/suspend/suspend_controller.cpp | 21 ++++---- .../native/src/wakeup/wakeup_controller.cpp | 30 +++-------- 4 files changed, 59 insertions(+), 50 deletions(-) diff --git a/services/native/include/power_state_machine.h b/services/native/include/power_state_machine.h index 65678146..502d870f 100644 --- a/services/native/include/power_state_machine.h +++ b/services/native/include/power_state_machine.h @@ -77,6 +77,7 @@ public: CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG, CHECK_PRE_BRIGHT_AUTH_TIMEOUT_MSG, CHECK_PROXIMITY_SCREEN_OFF_MSG, + SET_INTERNAL_SCREEN_STATE_MSG, }; class PowerStateCallbackDeathRecipient : public IRemoteObject::DeathRecipient { @@ -146,6 +147,7 @@ public: void RegisterPowerStateCallback(const sptr& callback, bool isSync = true); void UnRegisterPowerStateCallback(const sptr& callback); void SetDelayTimer(int64_t delayTime, int32_t event); + void SetDelayTimer(int64_t delayTime, int32_t event, FFRTTask& task); void CancelDelayTimer(int32_t event); void ResetInactiveTimer(bool needPrintLog = true); void ResetSleepTimer(); @@ -227,8 +229,9 @@ public: bool IsSettingState(PowerState state); void SetEnableDoze(bool enable); bool SetDozeMode(DisplayState state); - void SetInternalScreenDisplayPower(DisplayState state, StateChangeReason reason); - void SetInternalScreenBrightness(); +#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT + void SetInternalScreenDisplayState(DisplayState state, StateChangeReason reason); +#endif private: enum PreBrightState : uint32_t { @@ -408,6 +411,7 @@ private: std::atomic isDozeEnabled_ {false}; #ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT std::atomic externalScreenNumber_ {0}; + std::mutex internalScreenStateMutex_; #endif ProximityNormalController proximityNormalController_; bool SetDreamingState(StateChangeReason reason); diff --git a/services/native/src/power_state_machine.cpp b/services/native/src/power_state_machine.cpp index 4cf06fb9..c09fb3b9 100644 --- a/services/native/src/power_state_machine.cpp +++ b/services/native/src/power_state_machine.cpp @@ -298,6 +298,11 @@ void PowerStateMachine::EmplaceAwake() HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "REASON", PowerUtils::GetReasonTypeString(reason).c_str()); #endif mDeviceState_.screenState.lastOnTime = GetTickCount(); +#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT + if (reason == StateChangeReason::STATE_CHANGE_REASON_SWITCH && IsSwitchOpen() && IsScreenOn()) { + SetInternalScreenDisplayState(DisplayState::DISPLAY_ON, reason); + } +#endif auto targetState = DisplayState::DISPLAY_ON; if (reason == StateChangeReason::STATE_CHANGE_REASON_PRE_BRIGHT_AUTH_FAIL_SCREEN_OFF) { if (isDozeEnabled_) { @@ -306,12 +311,6 @@ void PowerStateMachine::EmplaceAwake() targetState = DisplayState::DISPLAY_OFF; } } -#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT - if (reason == StateChangeReason::STATE_CHANGE_REASON_SWITCH && IsSwitchOpen() && IsScreenOn()) { - SetInternalScreenDisplayPower(DisplayState::DISPLAY_ON, reason); - SetInternalScreenBrightness(); - } -#endif uint32_t ret = this->stateAction_->SetDisplayState(targetState, reason); if (ret != ActionResult::SUCCESS) { POWER_HILOGE(FEATURE_POWER_STATE, "Failed to go to AWAKE, display error, ret: %{public}u", ret); @@ -1268,6 +1267,15 @@ void PowerStateMachine::SetDelayTimer(int64_t delayTime, int32_t event) } } +void PowerStateMachine::SetDelayTimer(int64_t delayTime, int32_t event, FFRTTask& task) +{ + if (!ffrtTimer_) { + POWER_HILOGE(FEATURE_ACTIVITY, "Failed to set delay timer, the timer pointer is null"); + return; + } + ffrtTimer_->SetTimer(event, task, delayTime); +} + void PowerStateMachine::CancelDelayTimer(int32_t event) { if (!ffrtTimer_) { @@ -1517,15 +1525,31 @@ bool PowerStateMachine::SetDozeMode(DisplayState state) return ret == ActionResult::SUCCESS; } -void PowerStateMachine::SetInternalScreenDisplayPower(DisplayState state, StateChangeReason reason) -{ - this->stateAction_->SetInternalScreenDisplayPower(state, reason); -} - -void PowerStateMachine::SetInternalScreenBrightness() +#ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT +void PowerStateMachine::SetInternalScreenDisplayState(DisplayState state, StateChangeReason reason) { - this->stateAction_->SetInternalScreenBrightness(); + std::lock_guard lock(internalScreenStateMutex_); + if (state == DisplayState::DISPLAY_ON) { +#ifdef POWER_MANAGER_POWER_ENABLE_S4 + if (IsHibernating()) { + POWER_HILOGI(FEATURE_POWER_STATE, "[UL_POWER] Do not power the internal screen while hibernating"); + return; + } +#endif + if (!IsSwitchOpen()) { + POWER_HILOGI(FEATURE_POWER_STATE, "[UL_POWER] Do not power the internal screen while switch is close"); + return; + } + this->stateAction_->SetInternalScreenDisplayPower(state, reason); + this->stateAction_->SetInternalScreenBrightness(); + } else if (state == DisplayState::DISPLAY_OFF) { + this->stateAction_->SetInternalScreenDisplayPower(state, reason); + } else { + POWER_HILOGW( + FEATURE_POWER_STATE, "[UL_POWER] SetInternalScreenDisplayState, invalid display state: %{public}u", state); + } } +#endif bool PowerStateMachine::CheckRunningLock(PowerState state) { diff --git a/services/native/src/suspend/suspend_controller.cpp b/services/native/src/suspend/suspend_controller.cpp index 20ad747b..da285dba 100644 --- a/services/native/src/suspend/suspend_controller.cpp +++ b/services/native/src/suspend/suspend_controller.cpp @@ -498,14 +498,8 @@ std::shared_ptr SuspendController::GetSpecifiedSuspendMonitor(Su #ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT void SuspendController::PowerOffInternalScreen(SuspendDeviceType type) { - using namespace OHOS::Rosen; - auto changeReason = stateMachine_->GetReasonBySuspendType(type); - auto dmsReason = PowerUtils::GetDmsReasonByPowerReason(changeReason); - uint64_t screenId = DisplayManagerLite::GetInstance().GetInternalScreenId(); - bool ret = DisplayManagerLite::GetInstance().SetScreenPowerById(screenId, ScreenPowerState::POWER_OFF, dmsReason); - POWER_HILOGI(FEATURE_SUSPEND, - "[UL_POWER] Power off internal screen, reason = %{public}u, screenId = %{public}u, ret = %{public}d", dmsReason, - static_cast(screenId), ret); + stateMachine_->SetInternalScreenDisplayState( + DisplayState::DISPLAY_OFF, stateMachine_->GetReasonBySuspendType(type)); } void SuspendController::PowerOffAllScreens(SuspendDeviceType type) @@ -530,10 +524,13 @@ bool SuspendController::IsPowerOffInernalScreenOnlyScene( void SuspendController::ProcessPowerOffInternalScreenOnly(const sptr& pms, SuspendDeviceType reason) { - POWER_HILOGI( - FEATURE_SUSPEND, "[UL_POWER] Power off internal screen when closing switch is configured as no operation"); - PowerOffInternalScreen(reason); - pms->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_SWITCH, false); + FFRTTask powerOffInternalScreenTask = [this, pms, reason]() { + POWER_HILOGI( + FEATURE_SUSPEND, "[UL_POWER] Power off internal screen when closing switch is configured as no operation"); + PowerOffInternalScreen(reason); + pms->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_SWITCH, false); + }; + stateMachine_->SetDelayTimer(0, PowerStateMachine::SET_INTERNAL_SCREEN_STATE_MSG, powerOffInternalScreenTask); } #endif diff --git a/services/native/src/wakeup/wakeup_controller.cpp b/services/native/src/wakeup/wakeup_controller.cpp index bb2e2a1f..973b8244 100644 --- a/services/native/src/wakeup/wakeup_controller.cpp +++ b/services/native/src/wakeup/wakeup_controller.cpp @@ -701,26 +701,7 @@ bool WakeupController::CheckEventReciveTime(WakeupDeviceType wakeupType) #ifdef POWER_MANAGER_ENABLE_EXTERNAL_SCREEN_MANAGEMENT void WakeupController::PowerOnInternalScreen(WakeupDeviceType type) { -#ifdef POWER_MANAGER_POWER_ENABLE_S4 - if (stateMachine_->IsHibernating()) { - POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER] Do not power the internal screen while hibernating"); - return; - } -#endif - if (!stateMachine_->IsSwitchOpen()) { - POWER_HILOGI(FEATURE_SUSPEND, "[UL_POWER] Do not power the internal screen while switch is close"); - return; - } - - auto changeReason = stateMachine_->GetReasonByWakeType(type); - auto dmsReason = PowerUtils::GetDmsReasonByPowerReason(changeReason); - uint64_t screenId = Rosen::DisplayManagerLite::GetInstance().GetInternalScreenId(); - bool ret = Rosen::DisplayManagerLite::GetInstance().SetScreenPowerById( - screenId, Rosen::ScreenPowerState::POWER_ON, dmsReason); - stateMachine_->SetInternalScreenBrightness(); - POWER_HILOGI(FEATURE_WAKEUP, - "[UL_POWER] Power on internal screen, reason = %{public}u, screenId = %{public}u, ret = %{public}d", dmsReason, - static_cast(screenId), ret); + stateMachine_->SetInternalScreenDisplayState(DisplayState::DISPLAY_ON, stateMachine_->GetReasonByWakeType(type)); } void WakeupController::PowerOnAllScreens(WakeupDeviceType type) @@ -751,9 +732,12 @@ bool WakeupController::IsPowerOnInernalScreenOnlyScene(WakeupDeviceType reason) void WakeupController::ProcessPowerOnInternalScreenOnly(const sptr& pms, WakeupDeviceType reason) { - POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Power on internal screen only when external screen is on"); - PowerOnInternalScreen(reason); - pms->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_SWITCH, false); + FFRTTask powerOnInternalScreenTask = [this, pms, reason]() { + POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Power on internal screen only when external screen is on"); + PowerOnInternalScreen(reason); + pms->RefreshActivity(GetTickCount(), UserActivityType::USER_ACTIVITY_TYPE_SWITCH, false); + }; + stateMachine_->SetDelayTimer(0, PowerStateMachine::SET_INTERNAL_SCREEN_STATE_MSG, powerOnInternalScreenTask); } #endif -- Gitee