积分184 / 贡献0

提问0答案被采纳0文章7

[经验分享] OpenHarmony4.0源码解析之电源管理的熄屏和休眠机制 原创 精华

深开鸿_王奎 显示全部楼层 发表于 2023-12-4 21:03:11

OpenHarmony4.0源码解析之电源管理的熄屏和休眠机制

作者:王奎

简介

电源管理服务组件是OpenHarmony的电源管理子系统中的重要组件之一,主要提供如下功能:

  1. 重启系统。
  2. 管理休眠运行锁。
  3. 系统电源状态查询。

本文主要分析电源管理服务组件的息屏、休眠的关键流程代码,其他流程将在后续的系列文章中描述。其中,电源管理接口和运行锁接口相关内容不再赘述。文中涉及到HDF驱动框架、SystemAbility框架等内容只是简单提及,不做详细分析。

电源管理子系统之电源管理服务组件架构图:

power-management-subsystem-architecture.png

代码目录

/base/powermgr/power_manager
├── figures                     # 架构图
├── frameworks                  # Framework层
│   ├── napi                    # NAPI层
│   └── native                  # Native层
├── interfaces                  # 接口层
│   └── inner_api               # 内部接口
├── sa_profile                  # SA 配置文件
├── services                    # 服务层
│   ├── native                  # Native 层
│   └── zidl                    # Zidl 接口层
├── test                        # 测试用例
│   ├── fuzztest                # Fuzz 测试
│   ├── unittest                # 单元测试
│   ├── systemtest              # 系统测试
│   └── utils                   # 测试工具
└── utils                       # 工具和通用层

电源管理息屏、休眠流程

电源管理的息屏锁屏与否,依赖电源管理的配置文件:power_mode_config.xml的参数设置硬件中的位置有三处进行访问:

/etc/power_config/power_mode_config.xml 
    /vendor/etc/power_config/power_mode_config.xml 
    /system/etc/power_config/power_mode_config.xml

根据PowerSaveMode::PowerSaveMode()的实现(构造函数)可知,访问顺序是由上而下,若第一个不能正常解析,则向后递推。具体代码如下:

(../base/powermgr/power_manager/services/native/src/power_save_mode.cpp)

...
const std::string POWER_MODE_CONFIG_PATH =         "etc/power_config/power_mode_config.xml";
const std::string VENDOR_POWER_MODE_CONFIG_PATH = "/vendor/etc/power_config/power_mode_config.xml";
const std::string SYSTEM_POWER_MODE_CONFIG_PATH = "/system/etc/power_config/power_mode_config.xml";
...
PowerSaveMode::PowerSaveMode()
{
    POWER_HILOGD(FEATURE_POWER_MODE, "Start to parse power_mode_config.xml");

    char buf[MAX_PATH_LEN];
    // 若GetOneCfgFile(POWER_MODE_CONFIG_PATH...)成功,则解析之
    char* path = GetOneCfgFile(POWER_MODE_CONFIG_PATH.c_str(), buf, MAX_PATH_LEN);
    if (path != nullptr && *path != '\0') {
        if (!StartXMlParse(path)) {
            POWER_HILOGE(FEATURE_POWER_MODE, "policy config file power_mode_config.xml err");
        }
        return;
    }

    //否则,则解析VENDOR_POWER_MODE_CONFIG_PATH
    if (!StartXMlParse(VENDOR_POWER_MODE_CONFIG_PATH)) {
        POWER_HILOGI(FEATURE_POWER_MODE, "No vendor power_mode_config.xml, start to parse system config");
        // 若VENDOR_POWER_MODE_CONFIG_PATH失败,解析SYSTEM_POWER_MODE_CONFIG_PATH
        StartXMlParse(SYSTEM_POWER_MODE_CONFIG_PATH);
    }
}

展开power_mode_config.xml配置文件,解读息屏休眠相关参数:proxy id、switch id 101、102。不同的产品可对这些参数按需进行配置。

<!--
    Power Mode Definitions:
    MODE_NORMAL = 600,
    MODE_POWER_SAVE = 601,
    MODE_PERFORMANCE = 602,
    MODE_EXTREME_POWER_SAVE = 603,
-->
<!--
    Action Definitions:
    DisplayOffTime = 101,
    SystemAutoSleepTime = 102,
    AutoAdjustBrightness = 103,
    AutoWindowRotation = 107,
    SystemBrightness = 115,
    VibratorsState = 120,
-->
<switch_proxy version="1">
    <proxy id="600">                                        <!--powerMode: 600为默认-->
        <switch id="101" value="30000" recover_flag="0"/>   <!--101:自动息屏时间(ms),若为-1,则不会息屏,也就不会有锁屏、休眠 -->
        <switch id="102" value="0" recover_flag="0"/>       <!--102:自动休眠时间(ms),若为-1,则不休眠;0表示息屏后立即休眠 -->
        <switch id="103" value="-1" recover_flag="0"/>      
        <switch id="107" value="1" recover_flag="0"/>
        <switch id="115" value="102" recover_flag="0"/>
        <switch id="120" value="1" recover_flag="0"/>
    </proxy>
    <proxy id="601">
        <switch id="101" value="10000" recover_flag="0"/>
        <switch id="102" value="5000" recover_flag="0"/>
        <switch id="103" value="-1" recover_flag="0"/>
        <switch id="107" value="-1" recover_flag="0"/>
        <switch id="115" value="50" recover_flag="0"/>
        <switch id="120" value="-1" recover_flag="0"/>
    </proxy>
    <proxy id="602">
        <switch id="101" value="-1" recover_flag="0"/>
        <switch id="102" value="-1" recover_flag="0"/>
        <switch id="103" value="-1" recover_flag="0"/>
        <switch id="107" value="1" recover_flag="0"/>
        <switch id="115" value="255" recover_flag="0"/>
        <switch id="120" value="1" recover_flag="0"/>
    </proxy>
    <proxy id="603">
        <switch id="101" value="5000" recover_flag="0"/>
        <switch id="102" value="1000" recover_flag="0"/>
        <switch id="103" value="-1" recover_flag="0"/>
        <switch id="107" value="-1" recover_flag="0"/>
        <switch id="115" value="25" recover_flag="0"/>
        <switch id="120" value="-1" recover_flag="0"/>
    </proxy>
</switch_proxy>

硬件上电后,电源管理服务被打包到foundation进程,将会进行PowerMgrService初始化。其中powerStateMachine也在PowerMgrService中进行初始化。

初始化 PowerStateMachine

(由PowerMgrService服务初始化, std::map<PowerState, std::sharedptr<StateController>> controllerMap)

System Ability管理模块调用PowerMgrService的启动函数OnStart(),实现电源管理服务组件的启动:

PowerMgrService::OnStart

启动函数OnStart(),最终分别通过调用 PowerStateMachine: Init()-> InitStateMap() 和PowerStateMachine::InitState(),实现状态机的初始化和状态机的初态的设置。主要流程有:

1)调用Init()函数,实现PowerStateMachine状态机的初始化;

2)调用AddSystemAbilityListener(),监听依赖的服务,在 OnAddSystemAbility中调用RegisterBootCompletedCallback(),并根据具体的设备信息, 设置状态机的初始状态。

// PowerMgrService:  OnStart()->Init()->PowerStateMachineInit()->PowerStateMachine::Init()
// PowerMgrService:  OnStart()->Init()->RegisterBootCompletedCallback()->PowerStateMachine::InitState()
void PowerMgrService::OnStart()
{
    POWER_HILOGD(COMP_SVC, "Power Management startup");
    if (ready_) {
        POWER_HILOGW(COMP_SVC, "OnStart is ready, nothing to do");
        return;
    }

    // Init()方法,进行PowerStateMachine初始化,并根据设备信息,设置初始状态。
    if (!Init()) {
        POWER_HILOGE(COMP_SVC, "Call init fail");
        return;
    }
    /* 监听依赖的服务:DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID/DISPLAY_MANAGER_SERVICE_ID
       若监听到依赖的服务已具备,则调用PowerMgrService::OnAddSystemAbility(...)
    */
    AddSystemAbilityListener(DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID);
    AddSystemAbilityListener(DISPLAY_MANAGER_SERVICE_ID);

    // 注册HdiStatusListener
    SystemSuspendController::GetInstance().RegisterHdiStatusListener();
    if (!Publish(DelayedSpSingleton<PowerMgrService>::GetInstance())) {
        POWER_HILOGE(COMP_SVC, "Register to system ability manager failed");
        return;
    }
    ready_ = true;
    POWER_HILOGI(COMP_SVC, "Add system ability success");
}

// override基类方法,若DISPLAY_MANAGER_SERVICE_ID注册成功,则调用RegisterBootCompletedCallback()
void PowerMgrService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
{
    POWER_HILOGI(COMP_SVC, "systemAbilityId=%{public}d, deviceId=%{private}s Add",
        systemAbilityId, deviceId.c_str());
    if (systemAbilityId == DISPLAY_MANAGER_SERVICE_ID) {
        // 调用该方法,设置PowerStateMachine初始状态
        RegisterBootCompletedCallback();
    }
}

PowerMgrService::Init()

该方法,会调用的PowerMgrService::PowerStateMachineInit(),对PowerStateMachine的初始化。

bool PowerMgrService::Init()
{
    POWER_HILOGI(COMP_SVC, "Init start");
    // 运行锁管理初始化
    if (!runningLockMgr_) {
        runningLockMgr_ = std::make_shared<RunningLockMgr>(pms);
    }
    if (!runningLockMgr_->Init()) {
        POWER_HILOGE(COMP_SVC, "Running lock init fail");
        return false;
    }
    if (!shutdownController_) {
        shutdownController_ = std::make_shared<ShutdownController>();
    }

    // PowerStateMachine初始化  
    if (!PowerStateMachineInit()) {
        POWER_HILOGE(COMP_SVC, "Power state machine init fail");
    }

    POWER_HILOGI(COMP_SVC, "Init success");
    return true;
}

bool PowerMgrService::PowerStateMachineInit()
{
    if (powerStateMachine_ == nullptr) {
        powerStateMachine_ = std::make_shared<PowerStateMachine>(pms);

        // 调用powerStateMachine::Init()进行初始化状态机的所有状态及行为
        if (!(powerStateMachine_->Init())) {
            POWER_HILOGE(COMP_SVC, "Power state machine start fail!");
            return false;
        }
    }
    if (powerMgrNotify_ == nullptr) {
        powerMgrNotify_ = std::make_shared<PowerMgrNotify>();
        powerMgrNotify_->RegisterPublishEvents();
    }
    return true;
}

PowerStateMachine::Init():

​ 通过PowerStateMachine::InitStateMap(),实现对状态机的初始化

bool PowerStateMachine::Init()
{
    POWER_HILOGD(FEATURE_POWER_STATE, "Start init");
    queue_ = std::make_shared<FFRTQueue>("power_state_machine");
    if (queue_ == nullptr) {
        return false;
    }
    // 见本段代码底部
    stateAction_ = PowerMgrFactory::GetDeviceStateAction();

    //初始化状态机的多种状态:awake/inactive/sleep... 
    InitStateMap();
    if (powerStateCBDeathRecipient_ == nullptr) {
        powerStateCBDeathRecipient_ = new PowerStateCallbackDeathRecipient();
    }
    POWER_HILOGD(FEATURE_POWER_STATE, "Init success");
    return true;
}

// 初始化 状态机
void PowerStateMachine::InitStateMap()
{
    EmplaceAwake();    // Awake  
    EmplaceFreeze();   // Freeze:TODO
    EmplaceInactive(); // Inactive
    EmplaceStandBy();  // StandBy:TODO
    EmplaceDoze();     // Doze:TODO
    EmplaceSleep();    // Sleep     
    EmplaceHibernate();// Hibernate:TODO
    EmplaceShutdown(); // Shutdown:TODO
}

// -----------------------------------------------------------------------
// 注:工厂方法代码实现    
unique_ptr<IDeviceStateAction> PowerMgrFactory::GetDeviceStateAction()
{
#ifdef HAS_DISPLAY_MANAGER_PART
    return make_unique<DeviceStateAction>();
#else
    return make_unique<DefaultDeviceStateAction>();
#endif
}
-----------------------------------------------------------------------

接下来,开始本篇的关键的部分代码,EmplaceAwake() /EmplaceInactive()/EmplaceSleep。(其他状态暂未实现)

EmplaceAwake()

调用公共函数DeviceStateAction::SetDisplayState(...),设置DisplayState为DISPLAY_ON成功后,调用ResetInactiveTimer(),开启Inactive倒计时。

void PowerStateMachine::EmplaceAwake()
{
    controllerMap_.emplace(PowerState::AWAKE,
        std::make_shared<StateController>(PowerState::AWAKE, shared_from_this(), [this](StateChangeReason reason) {
            POWER_HILOGI(FEATURE_POWER_STATE, "StateController_AWAKE lambda start");
            mDeviceState_.screenState.lastOnTime = GetTickCount();

            // 调用DeviceStateAction::SetDisplayState()
            uint32_t ret = this->stateAction_->SetDisplayState(DisplayState::DISPLAY_ON, reason);
            if (ret != ActionResult::SUCCESS) {
                POWER_HILOGE(FEATURE_POWER_STATE, "Failed to go to AWAKE, display error, ret: %{public}u", ret);
                return TransitResult::DISPLAY_ON_ERR;
            }
            // 进入awake状态会ResetInactiveTimer()
            ResetInactiveTimer();
            return TransitResult::SUCCESS;
        }));
}

​ ResetInactiveTimer()的部分,将在Awake流程中继续分析,此处不必赘述。

EmplaceInactive():

​ 根据enableDisplaySuspend_参数,传入DISPLAY_OFF or DISPLAY_SUSPEND,调用公共函数DeviceStateAction::SetDisplayState(...)。

void PowerStateMachine::EmplaceInactive()
{
    controllerMap_.emplace(PowerState::INACTIVE,
        std::make_shared<StateController>(PowerState::INACTIVE, shared_from_this(), [this](StateChangeReason reason) {
            POWER_HILOGI(FEATURE_POWER_STATE, "StateController_INACTIVE lambda start");
            mDeviceState_.screenState.lastOffTime = GetTickCount();
            DisplayState state = DisplayState::DISPLAY_OFF;
            // 该参数由用户显示调用SetDisplaySuspend(...)进行设置,默认为false
            if (enableDisplaySuspend_) {
                POWER_HILOGI(FEATURE_POWER_STATE, "Display suspend enabled");
                state = DisplayState::DISPLAY_SUSPEND;
            }
            /* PowerStateMachine::Init()初始化时候调用工厂方法指定对象指针
               stateAction_ = PowerMgrFactory::GetDeviceStateAction(); 
            */
            uint32_t ret = this->stateAction_->SetDisplayState(state, reason);
            if (ret != ActionResult::SUCCESS) {
                POWER_HILOGE(FEATURE_POWER_STATE, "Failed to go to INACTIVE, display error, ret: %{public}u", ret);
                return TransitResult::DISPLAY_OFF_ERR;
            }
            return TransitResult::SUCCESS;
        }));
}

EmplaceSleep()

void PowerStateMachine::EmplaceSleep()
{
    controllerMap_.emplace(PowerState::SLEEP,
        std::make_shared<StateController>(PowerState::SLEEP, shared_from_this(), [this](StateChangeReason reason) {
            POWER_HILOGI(FEATURE_POWER_STATE, "StateController_SLEEP lambda start");
            return TransitResult::SUCCESS;
        }));
}

接下来,重点看一下公共函数DeviceStateAction::SetDisplayState(...)及其

其中有2个主要过程:

1) 若DisplayState为DISPLAY_ON/DISPLAY_OFF,将调用DisplayManager::WakeUpBegin(...)/DisplayManager::SuspendBegin(...);
  1) DisplayPowerMgrClient::SetDisplayState(...)
uint32_t DeviceStateAction::SetDisplayState(const DisplayState state, StateChangeReason reason)
{
    POWER_HILOGD(FEATURE_POWER_STATE,
        "Action: SetDisplayState: DisplayState=%{public}d, StateChangeReason=%{public}d, Coordinated=%{public}d",
        static_cast<uint32_t>(state), static_cast<uint32_t>(reason), coordinated_);

    // 若当前状态与待设置状态一致,则直接返回
    DisplayState currentState = GetDisplayState();
    if (state == currentState) {
        POWER_HILOGD(FEATURE_POWER_STATE, "Already in state: %{public}d", static_cast<uint32_t>(state));
        return ActionResult::SUCCESS;
    }

    // 注册DisplayState的回调函数
    if (!isRegister_) {
        isRegister_ = DisplayPowerMgrClient::GetInstance().RegisterCallback(dispCallback_);
        POWER_HILOGI(FEATURE_POWER_STATE, "Register Callback is %{public}d", isRegister_);
    }

    DisplayPowerMgr::DisplayState dispState = DisplayPowerMgr::DisplayState::DISPLAY_ON;
    PowerStateChangeReason dispReason = IsLockScreen(reason) ?
        PowerStateChangeReason::POWER_BUTTON : PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION;
    switch (state) {
        case DisplayState::DISPLAY_ON: {
            dispState = DisplayPowerMgr::DisplayState::DISPLAY_ON;

            // 若当前为DisplayState::DISPLAY_OFF,则调用DisplayManager::WakeUpBegin(...),通知相关模块,进行唤醒流程。
            if (currentState == DisplayState::DISPLAY_OFF && reason != StateChangeReason::STATE_CHANGE_REASON_SENSOR) {
                std::string identity = IPCSkeleton::ResetCallingIdentity();
                DisplayManager::GetInstance().WakeUpBegin(dispReason);
                IPCSkeleton::SetCallingIdentity(identity);
            }
            break;
        }
        case DisplayState::DISPLAY_DIM:
            dispState = DisplayPowerMgr::DisplayState::DISPLAY_DIM;
            break;
        case DisplayState::DISPLAY_OFF: {
            dispState = DisplayPowerMgr::DisplayState::DISPLAY_OFF;

            // 若当前状态为DisplayState::DISPLAY_ON,则调用DisplayManager::SuspendBegin(...)
            if ((currentState == DisplayState::DISPLAY_ON || currentState == DisplayState::DISPLAY_DIM) &&
                reason != StateChangeReason::STATE_CHANGE_REASON_SENSOR) {
                std::string identity = IPCSkeleton::ResetCallingIdentity();
                // 调用DM的SuspendBegin的接口,通知相关模块进行息屏、休眠前的处理,如锁屏等。
                DisplayManager::GetInstance().SuspendBegin(dispReason);
                IPCSkeleton::SetCallingIdentity(identity);
            }
            break;
        }
        case DisplayState::DISPLAY_SUSPEND:
            dispState = DisplayPowerMgr::DisplayState::DISPLAY_SUSPEND;
            break;
        default:
            break;
    }
    // 设置DisplayState 通知回调
    // 其中actionCallback_在WakeupController::Init()中调用stateAction->RegisterCallback(callback)来初始化
    dispCallback_->notify_ = actionCallback_;

    // 调用DisplayPowerMgrClient::SetDisplayState(dispState, reason),默认参数uint32_t id = 0
    bool ret = DisplayPowerMgrClient::GetInstance().SetDisplayState(dispState, reason);
    POWER_HILOGI(FEATURE_POWER_STATE, "Set display state finished, ret=%{public}d", ret);
    return ret ? ActionResult::SUCCESS : ActionResult::FAILED;
}

// --------------------------------------------------------------------------------------------------------------
// 注:OnDisplayStateChanged的回调中将调用DisplayManager::WakeUpEnd()/DisplayManager::SuspendEnd(),并notify相关完成事件
void DeviceStateAction::DisplayPowerCallback::OnDisplayStateChanged(uint32_t displayId,
    DisplayPowerMgr::DisplayState state, uint32_t reason)
{
    POWER_HILOGD(FEATURE_POWER_STATE, "Callback: OnDisplayStateChanged");
    int32_t mainDisp = DisplayPowerMgrClient::GetInstance().GetMainDisplayId();
    if (mainDisp < 0 || static_cast<uint32_t>(mainDisp) != displayId) {
        POWER_HILOGI(FEATURE_POWER_STATE, "It's not main display, skip!");
        return;
    }
    switch (state) {
        case DisplayPowerMgr::DisplayState::DISPLAY_ON: {
            if (StateChangeReason(reason) != StateChangeReason::STATE_CHANGE_REASON_SENSOR) {
                std::string identity = IPCSkeleton::ResetCallingIdentity();
                // DisplayManager::WakeUpEnd
                DisplayManager::GetInstance().WakeUpEnd();
                IPCSkeleton::SetCallingIdentity(identity);
            }
            NotifyDisplayActionDone(DISPLAY_ON_DONE);
            break;
        }
        case DisplayPowerMgr::DisplayState::DISPLAY_OFF: {
            if (StateChangeReason(reason) != StateChangeReason::STATE_CHANGE_REASON_SENSOR) {
                std::string identity = IPCSkeleton::ResetCallingIdentity();
                // DisplayManager::SuspendEnd
                DisplayManager::GetInstance().SuspendEnd();
                IPCSkeleton::SetCallingIdentity(identity);
            }
            // DeviceStateAction::NotifyDisplayActionDone()
            NotifyDisplayActionDone(DISPLAY_OFF_DONE);
            break;
        }
        default:
            break;
    }
    return;
}

void DeviceStateAction::DisplayPowerCallback::NotifyDisplayActionDone(uint32_t event)
{
    std::lock_guard lock(notifyMutex_);
    if (notify_ != nullptr) {
        notify_(event);
    }
}
// -----------------------------------------------------------------------------------------------

最后看一下DisplayPowerMgrClient::SetDisplayState()的实现的大概过程。(详细部分,将在Awake中说明。此处不做过多赘述)

// 这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxStub-->xxService
// 默认 uint32_t id = 0
bool DisplayPowerMgrClient::SetDisplayState(DisplayState state,
    PowerMgr::StateChangeReason reason, uint32_t id)
{
    auto proxy = GetProxy();
    RETURN_IF_WITH_RET(proxy == nullptr, false);
    return proxy->SetDisplayState(id, state, static_cast<uint32_t>(reason));
}
...
// 直接跳到DisplayPowerMgrService    
bool DisplayPowerMgrService::SetDisplayState(uint32_t id, DisplayState state, uint32_t reason)
{
    if (!Permission::IsSystem()) {
        return false;
    }

    // 根据id(默认为0),找到对应screenController
    DISPLAY_HILOGI(COMP_SVC, "SetDisplayState %{public}d, %{public}d", id, state);
    auto iterator = controllerMap_.find(id);
    if (iterator == controllerMap_.end()) {
        if (id != DEFALUT_DISPLAY_ID) {
            return false;
        }
        id = GetMainDisplayId();
        iterator = controllerMap_.find(id);
        if (iterator == controllerMap_.end()) {
            return false;
        }
    }

#ifdef HAS_SENSORS_SENSOR_PART
    if (id == GetMainDisplayId()) {
        DISPLAY_HILOGI(COMP_SVC, "change ambient sensor status");
        if (state == DisplayState::DISPLAY_ON) {
            ActivateAmbientSensor();
        } else if (state == DisplayState::DISPLAY_OFF) {
            DeactivateAmbientSensor();
        }
    }
#endif
    // 若是DISPLAY_OFF,则ScreenOffDelay
    if (state == DisplayState::DISPLAY_OFF) {
        if (!isDisplayDelayOff_) {
            DISPLAY_HILOGI(COMP_SVC, "screen off immediately");
            return iterator->second->UpdateState(state, reason);
        }
        displayId_ = id;
        displayState_ = state;
        displayReason_ = reason;
        FFRTTask task = [this]() { ScreenOffDelay(displayId_, displayState_, displayReason_); };
        g_screenOffDelayTaskHandle = FFRTUtils::SubmitDelayTask(task, displayOffDelayMs_, g_queue);
        tempState_ = iterator->second->SetDelayOffState();
        return true;
    } else if (state == DisplayState::DISPLAY_ON) {
        // 若是DISPLAY_ON,且isDisplayDelayOff_为真,则移除g_screenOffDelayTaskHandle
        if (isDisplayDelayOff_) {
            DISPLAY_HILOGI(COMP_SVC, "need remove delay task");
            FFRTUtils::CancelTask(g_screenOffDelayTaskHandle, g_queue);
            isDisplayDelayOff_ = false;
            tempState_ = iterator->second->SetOnState();
            return true;
        }
    }
    // 以上都不是,则 ScreenController::UpdateState
    return iterator->second->UpdateState(state, reason);
}

PowerMgrService::RegisterBootCompletedCallback()

// 设置PowerStateMachine初始状态    
void PowerMgrService::RegisterBootCompletedCallback()
{
    //初始化回调函数g_bootCompletedCallback
    g_bootCompletedCallback = []() {
        POWER_HILOGI(COMP_SVC, "BootCompletedCallback triggered");
        auto power = DelayedSpSingleton<PowerMgrService>::GetInstance();
        if (power == nullptr) {
            POWER_HILOGI(COMP_SVC, "get PowerMgrService fail");
            return;
        }
        if (DelayedSpSingleton<PowerSaveMode>::GetInstance()) {
            auto& powerModeModule = power->GetPowerModeModule();
            powerModeModule.EnableMode(powerModeModule.GetModeItem(), true);
        }
        auto powerStateMachine = power->GetPowerStateMachine();

        // 注册息屏时间的Observer
        powerStateMachine->RegisterDisplayOffTimeObserver();

        // 调用PowerStateMachine::InitState(),设置初始状态:awake(screenOn) or inactive(screenOff)
        powerStateMachine->InitState();

        // power的相关初始化
        power->GetShutdownDialog().KeyMonitorInit();
        power->HallSensorSubscriberInit();
        power->SwitchSubscriberInit();
        power->InputMonitorInit();
        power->SuspendControllerInit();
        power->WakeupControllerInit();
        power->VibratorInit();
        isBootCompleted_ = true;
    };
    WakeupRunningLock::Create();

    // 注册回调函数g_bootCompletedCallback至SysParam
    SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
}

powerStateMachine->InitState(): 根据当前的设备的状态信息,设置状态机的初态。

(本篇文章,我们只关息屏锁屏休眠等相关的函数实现,其他次要的函数/流程不做过多的阐述。)

// 调用PowerStateMachine::InitState(),根据设备信息,设置状态机初态:awake or inactive
void PowerStateMachine::InitState()
{
    POWER_HILOGD(FEATURE_POWER_STATE, "Init power state");
    if (IsScreenOn()) {
        // 设置初始状态:awake
        SetState(PowerState::AWAKE, StateChangeReason::STATE_CHANGE_REASON_INIT, true);
    } else {
        // 设置初始状态:inactive
        SetState(PowerState::INACTIVE, StateChangeReason::STATE_CHANGE_REASON_INIT, true);
    }
}

关键函数,状态设置函数:SetState()

bool PowerStateMachine::SetState(PowerState state, StateChangeReason reason, bool force)
{
    POWER_HILOGD(FEATURE_POWER_STATE, "state=%{public}d, reason=%{public}d, force=%{public}d", state, reason, force);
    auto iterator = controllerMap_.find(state);
    if (iterator == controllerMap_.end()) {
        return false;
    }
    std::shared_ptr<StateController> pController = iterator->second;
    if (pController == nullptr) {
        POWER_HILOGW(FEATURE_POWER_STATE, "StateController is not init");
        return false;
    }
    // TransitTo状态转换:PowerStateMachine::StateController::TransitTo
    // ignoreLock = true, 忽略任何锁,强制设置状态
    TransitResult ret = pController->TransitTo(reason, force);
    POWER_HILOGI(FEATURE_POWER_STATE, "StateController::TransitTo ret: %{public}d", ret);
    return (ret == TransitResult::SUCCESS || ret == TransitResult::ALREADY_IN_STATE);
}

SetState()->StateController::TransitTo(), ignoreLock为true时,则不进行runningLock检测

TransitResult PowerStateMachine::StateController::TransitTo(StateChangeReason reason, bool ignoreLock)
{
    POWER_HILOGD(FEATURE_POWER_STATE, "Start");
    std::shared_ptr<PowerStateMachine> owner = owner_.lock();
    if (owner == nullptr) {
        POWER_HILOGW(FEATURE_POWER_STATE, "owner is nullptr");
        return TransitResult::OTHER_ERR;
    }
    POWER_HILOGI(FEATURE_POWER_STATE, "Transit from %{public}s to %{public}s for %{public}s ignoreLock=%{public}d",
        PowerUtils::GetPowerStateString(owner->currentState_).c_str(),
        PowerUtils::GetPowerStateString(this->state_).c_str(),
        PowerUtils::GetReasonTypeString(reason).c_str(), ignoreLock);
    MatchState(owner->currentState_, owner->stateAction_->GetDisplayState());
    // 检查状态
    if (!CheckState()) {
        POWER_HILOGD(FEATURE_POWER_STATE, "Already in state: %{public}d", owner->currentState_);
        RecordFailure(owner->currentState_, reason, TransitResult::ALREADY_IN_STATE);
        return TransitResult::ALREADY_IN_STATE;
    }
    // ignoreLock为true时,则不进行runningLock检测
    if (!ignoreLock && !owner->CheckRunningLock(GetState())) {
        POWER_HILOGD(FEATURE_POWER_STATE, "Running lock block");
        RecordFailure(owner->currentState_, reason, TransitResult::LOCKING);
        return TransitResult::LOCKING;
    }
    // 进入相关状态的处理函数,详见PowerStateMachine::EmplaceXxx()
    TransitResult ret = action_(reason);
    if (ret == TransitResult::SUCCESS) {
        lastReason_ = reason;
        lastTime_ = GetTickCount();
        owner->currentState_ = GetState();
        // 状态成功后,会调用NotifyPowerStateChanged(...),
        owner->NotifyPowerStateChanged(owner->currentState_);
    } else {
        RecordFailure(owner->currentState_, reason, ret);
    }

    POWER_HILOGD(FEATURE_POWER_STATE, "Finish, result: %{public}d", ret);
    return ret;
}

Awake:

可由PowerStateMachine::InitState(),直接调用 SetState(PowerState::AWAKE, StateChangeReason::STATE_CHANGE_REASON_INIT, true)进入Awake状态;

由PowerStateMachine::EmplaceAwake()可知,进入Awake,主要进行两个步骤:

步骤1:DeviceStateAction::SetDisplayState

调用DeviceStateAction::SetDisplayState(DisplayState::DISPLAY_ON, reason);我们来一起看下公共函数的DISPLAY_ON分支:

uint32_t DeviceStateAction::SetDisplayState(const DisplayState state, StateChangeReason reason)
{
    ...
    if (!isRegister_) {
        isRegister_ = DisplayPowerMgrClient::GetInstance().RegisterCallback(dispCallback_);
        POWER_HILOGI(FEATURE_POWER_STATE, "Register Callback is %{public}d", isRegister_);
    }

    DisplayPowerMgr::DisplayState dispState = DisplayPowerMgr::DisplayState::DISPLAY_ON;
    PowerStateChangeReason dispReason = IsLockScreen(reason) ?
        PowerStateChangeReason::POWER_BUTTON : PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION;
    switch (state) {
        case DisplayState::DISPLAY_ON: {
            dispState = DisplayPowerMgr::DisplayState::DISPLAY_ON;            
            // 若当前为DisplayState::DISPLAY_OFF,则调用DisplayManager::WakeUpBegin(...),唤醒
            if (currentState == DisplayState::DISPLAY_OFF && reason != StateChangeReason::STATE_CHANGE_REASON_SENSOR) {
                std::string identity = IPCSkeleton::ResetCallingIdentity();
                DisplayManager::GetInstance().WakeUpBegin(dispReason);
                IPCSkeleton::SetCallingIdentity(identity);
            }
            break;
        }
        case DisplayState::DISPLAY_DIM:
            ...
            break;
        case DisplayState::DISPLAY_OFF: {
            ...
            break;
        }
        case DisplayState::DISPLAY_SUSPEND:
            ...
            break;
        default:
            break;
    }
    // DisplayState 通知回调
    dispCallback_->notify_ = actionCallback_;

    // 调用DisplayPowerMgrClient::SetDisplayState(dispState, reason)
    bool ret = DisplayPowerMgrClient::GetInstance().SetDisplayState(dispState, reason);
    POWER_HILOGI(FEATURE_POWER_STATE, "Set display state finished, ret=%{public}d", ret);
    return ret ? ActionResult::SUCCESS : ActionResult::FAILED;
}

DisplayPowerMgrClient::SetDisplayState,前面已经做了描述,此处做些差异化的描述

bool DisplayPowerMgrClient::SetDisplayState(DisplayState state,
    PowerMgr::StateChangeReason reason, uint32_t id)
{
    auto proxy = GetProxy();
    RETURN_IF_WITH_RET(proxy == nullptr, false);
    return proxy->SetDisplayState(id, state, static_cast<uint32_t>(reason));
}
...
bool DisplayPowerMgrService::SetDisplayState(uint32_t id, DisplayState state, uint32_t reason)
{
    if (!Permission::IsSystem()) {
        return false;
    }
    DISPLAY_HILOGI(COMP_SVC, "SetDisplayState %{public}d, %{public}d", id, state);
    auto iterator = controllerMap_.find(id);
    if (iterator == controllerMap_.end()) {
        if (id != DEFALUT_DISPLAY_ID) {
            return false;
        }
        id = GetMainDisplayId();
        iterator = controllerMap_.find(id);
        if (iterator == controllerMap_.end()) {
            return false;
        }
    }

#ifdef HAS_SENSORS_SENSOR_PART
    if (id == GetMainDisplayId()) {
        DISPLAY_HILOGI(COMP_SVC, "change ambient sensor status");
        if (state == DisplayState::DISPLAY_ON) {
            ActivateAmbientSensor();
        } else if (state == DisplayState::DISPLAY_OFF) {
            DeactivateAmbientSensor();
        }
    }
#endif

    if (state == DisplayState::DISPLAY_OFF) {
        ...
        return true;
    } else if (state == DisplayState::DISPLAY_ON) {
        // 取消ScreenOffDelayTask,并且SetOnState设置状态为:On
        if (isDisplayDelayOff_) {
            DISPLAY_HILOGI(COMP_SVC, "need remove delay task");
            FFRTUtils::CancelTask(g_screenOffDelayTaskHandle, g_queue);
            isDisplayDelayOff_ = false;
            tempState_ = iterator->second->SetOnState();
            return true;
        }
    }
    // UpdateState
    return iterator->second->UpdateState(state, reason);
}

步骤2:PowerStateMachine::ResetInactiveTimer

若配置文件中DisplayOffTime>=0, 则开启Inactive计时

void PowerStateMachine::ResetInactiveTimer()
{
    CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
    CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
    if (this->GetDisplayOffTime() < 0) {
        POWER_HILOGD(FEATURE_ACTIVITY, "Auto display off is disabled");
        return;
    }
    // 无Inactive的运行时锁,则在2/3的息屏时间后,发送消息CHECK_USER_ACTIVITY_TIMEOUT_MSG
    if (this->CheckRunningLock(PowerState::INACTIVE)) {
        const double DIMTIMERATE = 2.0/3;
        // SetDelayTimer():发送CHECK_USER_ACTIVITY_TIMEOUT_MSG,在2/3息屏时间后,进入DIM
        this->SetDelayTimer(
            this->GetDisplayOffTime() * DIMTIMERATE, PowerStateMachine::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
    }
}

SetDelayTimer中调用SubmitDelayTask,在delayTime后,将执行HandleActivityTimeout任务

void PowerStateMachine::SetDelayTimer(int64_t delayTime, int32_t event)
{
    POWER_HILOGD(FEATURE_ACTIVITY, "Set delay timer, delayTime=%{public}s, event=%{public}d",
        std::to_string(delayTime).c_str(), event);
    switch (event) {
        // CHECK_USER_ACTIVITY_TIMEOUT_MSG    
        case CHECK_USER_ACTIVITY_TIMEOUT_MSG: {
            std::lock_guard lock(ffrtMutex_);
            // 2/3的DisplayOffTime后,调用 HandleActivityTimeout
            FFRTTask task = std::bind(&PowerStateMachine::HandleActivityTimeout, this);
            userActivityTimeoutHandle_ = FFRTUtils::SubmitDelayTask(task, delayTime, queue_);
            break;
        }
        // CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG:  
        case CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG: {
            auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
            auto suspendController = pms->GetSuspendController();
            if (suspendController == nullptr) {
                POWER_HILOGW(FEATURE_ACTIVITY, "suspendController is nullptr");
                return;
            }
            // 余下的1/3息屏时间后,将调用 suspendController::HandleEvent 
            suspendController->HandleEvent(delayTime);
            break;
        }
        default: {
            break;
        }
    }
}

PowerStateMachine::HandleActivityTimeout实现代码:

void PowerStateMachine::HandleActivityTimeout()
{
    POWER_HILOGD(FEATURE_ACTIVITY, "Enter, displayState = %{public}d", stateAction_->GetDisplayState());
    DisplayState dispState = stateAction_->GetDisplayState();
    const uint32_t THREE = 3;
    if (!this->CheckRunningLock(PowerState::INACTIVE)) {
        POWER_HILOGI(FEATURE_ACTIVITY, "RunningLock is blocking to transit to INACTIVE");
        return;
    }

    if (dispState == DisplayState::DISPLAY_ON) {
        // 如果dispState为DISPLAY_ON,则进入DIM状态,变暗
        stateAction_->SetDisplayState(DisplayState::DISPLAY_DIM, StateChangeReason::STATE_CHANGE_REASON_TIMEOUT);

        // 并同时调用了SetDelayTimer,在余下的1/3时间到达后,调用suspendController::HandleEvent 
        if (this->GetDisplayOffTime() < 0) {
            POWER_HILOGD(FEATURE_ACTIVITY, "Auto display off is disabled");
            return;
        } else {
            // 余下的1/3 息屏时间到后,发送CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG,调用suspendController::HandleEvent
            SetDelayTimer(GetDisplayOffTime() / THREE, PowerStateMachine::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
        }
    } else {
        POWER_HILOGW(FEATURE_ACTIVITY, "Display is not on, ignore activity timeout, state = %{public}d", dispState);
        HandleActivityOffTimeout();
    }
}

余下的1/3 DisplayOffTime 到达后,将调用 TimeoutSuspendMonitor::HandleEvent():

void SuspendController::HandleEvent(int64_t delayTime)
{
    FFRTTask task = [&]() {
        g_monitorMutex.Lock();
        auto timeoutSuspendMonitor = monitorMap_.find(SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT);
        if (timeoutSuspendMonitor == monitorMap_.end()) {
            g_monitorMutex.Unlock();
            return;
        }
        g_monitorMutex.Unlock();
        auto monitor = timeoutSuspendMonitor->second;
        monitor->HandleEvent();
    };
    g_userActivityOffTimeoutHandle = FFRTUtils::SubmitDelayTask(task, delayTime, queue_);
}

TimeoutSuspendMonitor::HandleEvent()的具体的流程如下:即调用基类的notify方法。 通知对应的Listener,设置状态为Inactive。Listener由SuspendController::Init()初始化。

void TimeoutSuspendMonitor::HandleEvent()
{
    POWER_HILOGI(FEATURE_INPUT, "TimeoutSuspendMonitor HandleEvent");
    //调用基类方法
    Notify();
}
// --------------------------------------------------------------------------------------------------------------
// 基类的SuspendMonitor::Notify
void SuspendMonitor::Notify()
{
    if (listener_ == nullptr) {
        return;
    }
    //SuspendController::Init()会注册ControlListener,详见本段代码底部
    listener_(reason_, action_, delayMs_);
}

// ControlListener主要完成:1.设置 PowerState::INACTIVE 2.StartSleepTimer
void SuspendController::ControlListener(SuspendDeviceType reason, uint32_t action, uint32_t delay)
{
    auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
    if (pms == nullptr) {
        return;
    }

    if (pms->CheckDialogAndShuttingDown()) {
        return;
    }

    if (!pms->IsScreenOn()) {
        SuspendWhenScreenOff(reason, action, delay);
        return;
    }

    pid_t pid = IPCSkeleton::GetCallingPid();
    auto uid = IPCSkeleton::GetCallingUid();
    POWER_HILOGI(FEATURE_SUSPEND,
        "Try to suspend device, pid=%{public}d, uid=%{public}d, reason=%{public}d, action=%{public}u, "
        "delay=%{public}u" PRId32 "",
        pid, uid, reason, action, delay);
    bool force = true;
    if (reason == SuspendDeviceType::SUSPEND_DEVICE_REASON_TIMEOUT) {
        force = false;
    }
    if (stateMachine_ == nullptr) {
        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
        return;
    }

    // 将设置 PowerState::INACTIVE,
    bool ret = stateMachine_->SetState(
        PowerState::INACTIVE, stateMachine_->GetReasionBySuspendType(static_cast<SuspendDeviceType>(reason)), force);

    // 若成功,则StartSleepTimer
    if (ret) {
        StartSleepTimer(reason, action, delay);
    }
}

// StartSleepTimer会根据不同的参数,来调用HandleAction
void SuspendController::StartSleepTimer(SuspendDeviceType reason, uint32_t action, uint32_t delay)
{
    if (static_cast<SuspendAction>(action) == SuspendAction::ACTION_AUTO_SUSPEND) {
        delay = delay + SLEEP_DELAY_MS;
    }
    const int64_t& tmpRef = delay;
    int64_t timeout = GetTickCount() + tmpRef;
    if ((timeout > sleepTime_) && (sleepTime_ != -1)) {
        POWER_HILOGI(FEATURE_SUSPEND, "already have a sleep event (%{public}" PRId64 " > %{public}" PRId64 ")", timeout,
            sleepTime_);
        return;
    }
    sleepTime_ = timeout;
    sleepReason_ = reason;
    sleepAction_ = action;
    sleepDuration_ = delay;
    sleepType_ = action;
    if (delay == 0) {
        // action
        HandleAction(reason, action);
    } else {
        FFRTTask task = [this] {
            HandleAction(GetLastReason(), GetLastAction());
        };
        g_sleepTimeoutHandle = FFRTUtils::SubmitDelayTask(task, delay, queue_);
    }
}

// 根据action类型,调用不同的SuspendAction
void SuspendController::HandleAction(SuspendDeviceType reason, uint32_t action)
{
    switch (static_cast<SuspendAction>(action)) {
        case SuspendAction::ACTION_AUTO_SUSPEND:
            HandleAutoSleep(reason);
            break;
        case SuspendAction::ACTION_FORCE_SUSPEND:
            HandleForceSleep(reason);
            break;
        case SuspendAction::ACTION_HIBERNATE:
            HandleHibernate(reason);
            break;
        case SuspendAction::ACTION_SHUTDOWN:
            HandleShutdown(reason);
            break;
        case SuspendAction::ACTION_NONE:
        default:
            break;
    }
    sleepTime_ = -1;
    sleepAction_ = static_cast<uint32_t>(SuspendAction::ACTION_NONE);
}
//---------------------------------------------------------------------------------------------------------------------
// 注:SuspendController::Init()会注册ControlListener
// SuspendController::Init(),只贴出代码,不做过多的解读。
void SuspendController::Init()
{
    std::lock_guard lock(mutex_);
    queue_ = std::make_shared<FFRTQueue>("power_suspend_controller");
    if (queue_ == nullptr) {
        POWER_HILOGE(FEATURE_SUSPEND, "suspendQueue_ is null");
        return;
    }
    std::shared_ptr<SuspendSources> sources = SuspendSourceParser::ParseSources();
    sourceList_ = sources->GetSourceList();
    if (sourceList_.empty()) {
        POWER_HILOGE(FEATURE_SUSPEND, "InputManager is null");
        return;
    }

    for (auto source = sourceList_.begin(); source != sourceList_.end(); source++) {
        POWER_HILOGI(FEATURE_SUSPEND, "registered type=%{public}u action=%{public}u delayMs=%{public}u",
            (*source).GetReason(), (*source).GetAction(), (*source).GetDelay());
        std::shared_ptr<SuspendMonitor> monitor = SuspendMonitor::CreateMonitor(*source);
        if (monitor != nullptr && monitor->Init()) {
            POWER_HILOGI(FEATURE_SUSPEND, "register type=%{public}u", (*source).GetReason());

            // 注册 SuspendController::ControlListener,
            monitor->RegisterListener(std::bind(&SuspendController::ControlListener, this, std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3));
            g_monitorMutex.Lock();
            monitorMap_.emplace(monitor->GetReason(), monitor);
            g_monitorMutex.Unlock();
        }
    }
    sptr<SuspendPowerStateCallback> callback = new SuspendPowerStateCallback(shared_from_this());
    if (stateMachine_ == nullptr) {
        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
        return;
    }
    stateMachine_->RegisterPowerStateCallback(callback);
    RegisterSettingsObserver();
}

Inactive:

由Awake的流程可知,在最后的1/3息屏时间耗尽后,PowerStateMachine将会被置为Inactive。成功后,会调用 SuspendController::StartSleepTimer。由此可知,Inactive状态时,主要有2个步骤:

  1. StateController_INACTIVE: DeviceStateAction::SetDisplayState(...)
  2. StartSleepTimer。

设置状态为Inactive开始, SetState()->StateController::TransitTo() :若是HandleActivityOffTimeout,则 ignoreLock为false,将进行runningLock的检查;其他ignoreLock为true,则不会进行 runningLock检查。

我们先从EmplaceInactive()进入 Inactive状态:

void PowerStateMachine::EmplaceInactive()
{
    controllerMap_.emplace(PowerState::INACTIVE,
        std::make_shared<StateController>(PowerState::INACTIVE, shared_from_this(), [this](StateChangeReason reason) {
            POWER_HILOGI(FEATURE_POWER_STATE, "StateController_INACTIVE lambda start");
            mDeviceState_.screenState.lastOffTime = GetTickCount();
            DisplayState state = DisplayState::DISPLAY_OFF;
            if (enableDisplaySuspend_) {
                POWER_HILOGI(FEATURE_POWER_STATE, "Display suspend enabled");
                state = DisplayState::DISPLAY_SUSPEND;
            }
            // 传入不同的DisplayState,调用SetDisplayState
            uint32_t ret = this->stateAction_->SetDisplayState(state, reason);
            if (ret != ActionResult::SUCCESS) {
                POWER_HILOGE(FEATURE_POWER_STATE, "Failed to go to INACTIVE, display error, ret: %{public}u", ret);
                return TransitResult::DISPLAY_OFF_ERR;
            }
            return TransitResult::SUCCESS;
        }));
}

SetDisplayState()

进入Inactive,PowerMgrFactory::GetDeviceStateAction() ->SetDisplayState()

uint32_t DeviceStateAction::SetDisplayState(const DisplayState state, StateChangeReason reason)
{
    POWER_HILOGD(FEATURE_POWER_STATE,
        "Action: SetDisplayState: DisplayState=%{public}d, StateChangeReason=%{public}d, Coordinated=%{public}d",
        static_cast<uint32_t>(state), static_cast<uint32_t>(reason), coordinated_);

    DisplayState currentState = GetDisplayState();
    if (state == currentState) {
        POWER_HILOGD(FEATURE_POWER_STATE, "Already in state: %{public}d", static_cast<uint32_t>(state));
        return ActionResult::SUCCESS;
    }

    if (!isRegister_) {
        isRegister_ = DisplayPowerMgrClient::GetInstance().RegisterCallback(dispCallback_);
        POWER_HILOGI(FEATURE_POWER_STATE, "Register Callback is %{public}d", isRegister_);
    }

    DisplayPowerMgr::DisplayState dispState = DisplayPowerMgr::DisplayState::DISPLAY_ON;
    PowerStateChangeReason dispReason = IsLockScreen(reason) ?
        PowerStateChangeReason::POWER_BUTTON : PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION;
    switch (state) {
        case DisplayState::DISPLAY_ON: {
            ...
            break;
        }
        case DisplayState::DISPLAY_DIM:
            ...
            break;
        case DisplayState::DISPLAY_OFF: {

            dispState = DisplayPowerMgr::DisplayState::DISPLAY_OFF;
            if ((currentState == DisplayState::DISPLAY_ON || currentState == DisplayState::DISPLAY_DIM) &&
                reason != StateChangeReason::STATE_CHANGE_REASON_SENSOR) {
                std::string identity = IPCSkeleton::ResetCallingIdentity();
                 // 调用DM::SuspendBegin,通知开启DISPLAY_OFF前的准备工作,如锁屏等。
                DisplayManager::GetInstance().SuspendBegin(dispReason);
                IPCSkeleton::SetCallingIdentity(identity);
            }
            break;
        }
        case DisplayState::DISPLAY_SUSPEND:
            // 若为DISPLAY_SUSPEND,
            dispState = DisplayPowerMgr::DisplayState::DISPLAY_SUSPEND;
            break;
        default:
            break;
    }
    // 更新状态回调函数
    dispCallback_->notify_ = actionCallback_;
    // 调用息屏接口
    bool ret = DisplayPowerMgrClient::GetInstance().SetDisplayState(dispState, reason);
    POWER_HILOGI(FEATURE_POWER_STATE, "Set display state finished, ret=%{public}d", ret);
    return ret ? ActionResult::SUCCESS : ActionResult::FAILED;
}

由上可知,主要有两个步骤。

第一步,调用 DisplayManager::SuspendBegin(),并在状态回调函数中调用 DisplayManager::SuspendEnd():

void DeviceStateAction::DisplayPowerCallback::OnDisplayStateChanged(uint32_t displayId,
    DisplayPowerMgr::DisplayState state)
{
    POWER_HILOGD(FEATURE_POWER_STATE, "Callback: OnDisplayStateChanged");
    int32_t mainDisp = DisplayPowerMgrClient::GetInstance().GetMainDisplayId();
    if (mainDisp < 0 || static_cast<uint32_t>(mainDisp) != displayId) {
        POWER_HILOGI(FEATURE_POWER_STATE, "It's not main display, skip!");
        return;
    }
    switch (state) {
        case DisplayPowerMgr::DisplayState::DISPLAY_ON: {
            std::string identity = IPCSkeleton::ResetCallingIdentity();
            // WakeUpEnd
            DisplayManager::GetInstance().WakeUpEnd();
            IPCSkeleton::SetCallingIdentity(identity);
            NotifyDisplayActionDone(DISPLAY_ON_DONE);
            std::string name = LOCK_TAG_DISPLAY_POWER;
            SystemSuspendController::GetInstance().AcquireRunningLock(name);
            break;
        }
        case DisplayPowerMgr::DisplayState::DISPLAY_OFF: {
            std::string identity = IPCSkeleton::ResetCallingIdentity();

            // 此处可以看作相关模块挂起前的准备工作结束:SuspendEnd()
            DisplayManager::GetInstance().SuspendEnd();
            IPCSkeleton::SetCallingIdentity(identity);
            NotifyDisplayActionDone(DISPLAY_OFF_DONE);
            std::string name = LOCK_TAG_DISPLAY_POWER;
            SystemSuspendController::GetInstance().ReleaseRunningLock(name);
            break;
        }
        default:
            break;
    }
    return;
}

第二步,DisplayPowerMgrClient::SetDisplayState(),设置屏幕的亮度

// 这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxStub-->xxService
bool DisplayPowerMgrService::SetDisplayState(uint32_t id, DisplayState state, uint32_t reason)
{
    if (!Permission::IsSystem()) {
        return false;
    }

    // 根据id(默认为0),找到对应screenController
    DISPLAY_HILOGI(COMP_SVC, "SetDisplayState %{public}d, %{public}d", id, state);
    auto iterator = controllerMap_.find(id);
    if (iterator == controllerMap_.end()) {
        if (id != DEFALUT_DISPLAY_ID) {
            return false;
        }
        id = GetMainDisplayId();
        iterator = controllerMap_.find(id);
        if (iterator == controllerMap_.end()) {
            return false;
        }
    }

#ifdef HAS_SENSORS_SENSOR_PART
    if (id == GetMainDisplayId()) {
        DISPLAY_HILOGI(COMP_SVC, "change ambient sensor status");
        if (state == DisplayState::DISPLAY_ON) {
            ActivateAmbientSensor();
        } else if (state == DisplayState::DISPLAY_OFF) {
            DeactivateAmbientSensor();
        }
    }
#endif
    // 若是DISPLAY_OFF,则ScreenOffDelay
    // ScreenController::SetDelayOffState()
    if (state == DisplayState::DISPLAY_OFF) {
        if (!isDisplayDelayOff_) {
            DISPLAY_HILOGI(COMP_SVC, "screen off immediately");
            return iterator->second->UpdateState(state, reason);
        }
        displayId_ = id;
        displayState_ = state;
        displayReason_ = reason;
        FFRTTask task = [this]() { ScreenOffDelay(displayId_, displayState_, displayReason_); };
        g_screenOffDelayTaskHandle = FFRTUtils::SubmitDelayTask(task, displayOffDelayMs_, g_queue);
        tempState_ = iterator->second->SetDelayOffState();
        return true;
    } else if (state == DisplayState::DISPLAY_ON) {
        // 若是DISPLAY_ON,且isDisplayDelayOff_为真,则移除g_screenOffDelayTaskHandle
        // ScreenController::SetOnState()
        if (isDisplayDelayOff_) {
            DISPLAY_HILOGI(COMP_SVC, "need remove delay task");
            FFRTUtils::CancelTask(g_screenOffDelayTaskHandle, g_queue);
            isDisplayDelayOff_ = false;
            tempState_ = iterator->second->SetOnState();
            return true;
        }
    }
    // 以上都不是,则 ScreenController::UpdateState
    return iterator->second->UpdateState(state, reason);
}

ScreenOffDelay,将调用ScreenController::UpdateState;

void DisplayPowerMgrService::ScreenOffDelay(uint32_t id, DisplayState state, uint32_t reason)
{
    isDisplayDelayOff_ = false;
    DISPLAY_HILOGI(COMP_SVC, "ScreenOffDelay %{public}d, %{public}d,  %{public}d", id, state, reason);
    auto iterator = controllerMap_.find(id);
    if (iterator == controllerMap_.end()) {
        return;
    }
    // ScreenController::UpdateState
    setDisplayStateRet_ = iterator->second->UpdateState(state, reason);
}

ScreenController::SetOnState()/SetDelayOffState()

DisplayState ScreenController::SetOnState()
{
    DISPLAY_HILOGI(COMP_SVC, "Set the dispaly state is ON after overriding display on delay");
    state_ = DisplayState::DISPLAY_ON;
    return state_;
}
----------------------------------------------------------------------------------------------------------------
DisplayState ScreenController::SetDelayOffState()
{
    DISPLAY_HILOGI(COMP_SVC, "Set the dispaly state is DELAY OFF when overriding display off delay");
    state_ = DisplayState::DISPLAY_DELAY_OFF;
    return state_;
}

我们继续看一下UpdateState的实现。

bool ScreenController::UpdateState(DisplayState state, uint32_t reason)
{
    DISPLAY_HILOGI(FEAT_STATE, "UpdateState, state=%{public}u, current state=%{public}u",
                   static_cast<uint32_t>(state), static_cast<uint32_t>(state_));
    RETURN_IF_WITH_RET(state == state_, true);

    switch (state) {
        case DisplayState::DISPLAY_ON:
        case DisplayState::DISPLAY_OFF: {

            // 若state=DISPLAY_ON/DISPLAY_OFF 调用 ScreenAction::SetDisplayState
            // 绑定DisplayState的状态变化回调函数
            function<void(DisplayState)> callback =
                bind(&ScreenController::OnStateChanged, this, placeholders::_1, reason);
            // ScreenAction::SetDisplayState
            bool ret = action_->SetDisplayState(state, callback);
            if (!ret) {
                DISPLAY_HILOGW(FEAT_STATE, "Update display state failed, state=%{public}d", state);
                return ret;
            }
            break;
        }
        case DisplayState::DISPLAY_DIM:
        case DisplayState::DISPLAY_SUSPEND: {
            bool ret = action_->SetDisplayPower(state, stateChangeReason_);
            if (!ret) {
                DISPLAY_HILOGW(FEAT_STATE, "Update display power failed, state=%{public}d", state);
                return ret;
            }
            break;
        }
        default:
            break;
    }

    lock_guard lock(mutexState_);
    state_ = state;
    stateChangeReason_ = reason;

    DISPLAY_HILOGI(FEAT_STATE, "Update screen state to %{public}u", state);
    return true;
}

ScreenAction::SetDisplayState,将调用display_manager::SetDisplayState 设置,并最终将回调状态返回。

bool ScreenAction::SetDisplayState(DisplayState state, const std::function<void(DisplayState)>& callback)
{
    DISPLAY_HILOGI(FEAT_STATE, "displayId=%{public}u, state=%{public}u", displayId_, static_cast<uint32_t>(state));
    Rosen::DisplayState rds = Rosen::DisplayState::UNKNOWN;
    switch (state) {
        case DisplayState::DISPLAY_ON:
            rds = Rosen::DisplayState::ON;
            break;
        case DisplayState::DISPLAY_OFF:
            rds = Rosen::DisplayState::OFF;
            break;
        default:
            break;
    }
    std::string identity = IPCSkeleton::ResetCallingIdentity();
    // 调用DM::SetDisplayState()
    // foundation/window/window_manager/interfaces/innerkits/dm/display_manager.h
    // foundation/window/window_manager/dm/include/
    bool ret = Rosen::DisplayManager::GetInstance().SetDisplayState(rds,
        [callback](Rosen::DisplayState rosenState) {
            DISPLAY_HILOGI(FEAT_STATE, "SetDisplayState Callback:%{public}d", static_cast<uint32_t>(rosenState));
            DisplayState state;
            switch (rosenState) {
                case Rosen::DisplayState::ON:
                    state = DisplayState::DISPLAY_ON;
                    break;
                case Rosen::DisplayState::OFF:
                    state = DisplayState::DISPLAY_OFF;
                    break;
                default:
                    return;
            }
            // 状态回调
            callback(state);
    });
    IPCSkeleton::SetCallingIdentity(identity);
    // Notify screen state change event to battery statistics
    HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::DISPLAY, "SCREEN_STATE",
        HiviewDFX::HiSysEvent::EventType::STATISTIC, "STATE", static_cast<int32_t>(state));
    DISPLAY_HILOGI(FEAT_STATE, "SetDisplayState:%{public}d", ret);
    return ret;
}

回调处理函数ScreenController::OnStateChanged

void ScreenController::OnStateChanged(DisplayState state, uint32_t reason)
{
    auto pms = DelayedSpSingleton<DisplayPowerMgrService>::GetInstance();
    if (pms == nullptr) {
        DISPLAY_HILOGW(FEAT_STATE, "pms is nullptr");
        return;
    }

    // 进行功耗设置
    bool ret = action_->SetDisplayPower(state, stateChangeReason_);
    if (state == DisplayState::DISPLAY_ON) {
        // Restore the brightness before screen off
        uint32_t screenOnBrightness = GetScreenOnBrightness();
        UpdateBrightness(screenOnBrightness);
    }

    // 状态回调
    if (ret) {
        pms->NotifyStateChangeCallback(action_->GetDisplayId(), state, reason);
    }
}

设置功耗:ScreenAction::SetDisplayPower

bool ScreenAction::SetDisplayPower(DisplayState state, uint32_t reason)
{
    DISPLAY_HILOGI(FEAT_STATE, "displayId=%{public}u, state=%{public}u, reason=%{public}u",
                   displayId_, static_cast<uint32_t>(state), reason);
    Rosen::ScreenPowerState status = Rosen::ScreenPowerState::INVALID_STATE;
    switch (state) {
        case DisplayState::DISPLAY_ON:
            status = Rosen::ScreenPowerState::POWER_ON;
            break;
        case DisplayState::DISPLAY_DIM:
            status = Rosen::ScreenPowerState::POWER_STAND_BY;
            break;
        case DisplayState::DISPLAY_SUSPEND:
            status = Rosen::ScreenPowerState::POWER_SUSPEND;
            break;
        case DisplayState::DISPLAY_OFF:
            status = Rosen::ScreenPowerState::POWER_OFF;
            break;
        default:
            break;
    }

    bool ret = false;
    if (coordinated_ && reason == static_cast<uint32_t>(PowerMgr::StateChangeReason::STATE_CHANGE_REASON_TIMEOUT)) {
        ret = Rosen::ScreenManager::GetInstance().SetSpecifiedScreenPower(
            displayId_, status, Rosen::PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION);
    } else {
        ret = Rosen::ScreenManager::GetInstance().SetScreenPowerForAll(
            status, Rosen::PowerStateChangeReason::POWER_BUTTON);
    }
    DISPLAY_HILOGI(FEAT_STATE, "Set screen power, ret=%{public}d, coordinated=%{public}d", ret, coordinated_);
    return true;
}

Sleep:

由Awake的步骤2中的 StartSleepTimer可知,其将调用SuspendController::HandleAction来触发设备进入sleep状态。进入休眠状态,有两种方式,最终都将调用SystemSuspendController::Suspend(),来完成Sleep流程。

  1. HandleAutoSleep
  2. HandleForceSleep
void SuspendController::HandleAutoSleep(SuspendDeviceType reason)
{
    POWER_HILOGI(FEATURE_SUSPEND, "auto suspend by reason=%{public}d", reason);

    if (stateMachine_ == nullptr) {
        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
        return;
    }
    // 设置状态为sleep
    bool ret = stateMachine_->SetState(
        PowerState::SLEEP, stateMachine_->GetReasionBySuspendType(reason));
    if (ret) {
        POWER_HILOGI(FEATURE_SUSPEND, "State changed, set sleep timer");
        onForceSleep = false;
        TriggerSyncSleepCallback(false);
        SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, false);
    } else {
        POWER_HILOGI(FEATURE_SUSPEND, "auto suspend: State change failed");
    }
}

void SuspendController::HandleForceSleep(SuspendDeviceType reason)
{
    POWER_HILOGI(FEATURE_SUSPEND, "force suspend by reason=%{public}d", reason);
    if (stateMachine_ == nullptr) {
        POWER_HILOGE(FEATURE_SUSPEND, "Can't get PowerStateMachine");
        return;
    }
    bool ret = stateMachine_->SetState(
        PowerState::SLEEP, stateMachine_->GetReasionBySuspendType(reason), true);
    if (ret) {
        POWER_HILOGI(FEATURE_SUSPEND, "State changed, system suspend");
        onForceSleep = true;
        TriggerSyncSleepCallback(false);

        FFRTTask task = [this] {
            SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, true);
        };
        g_sleepTimeoutHandle = FFRTUtils::SubmitDelayTask(task, FORCE_SLEEP_DELAY_MS, queue_);
    } else {
        POWER_HILOGI(FEATURE_SUSPEND, "force suspend: State change failed");
    }
}

驱动部分实现具体的sleep的操作,即suspend:

void SystemSuspendController::Suspend(
    const std::function<void()>& onSuspend, const std::function<void()>& onWakeup, bool force)
{
    POWER_HILOGI(COMP_SVC, "The hdf interface");
    if (powerInterface_ == nullptr) {
        POWER_HILOGE(COMP_SVC, "The hdf interface is null");
        return;
    }
    if (force) {
        // 实现在PowerInterfaceImpl
        powerInterface_->ForceSuspend();
    } else {
        powerInterface_->StartSuspend();
    }
}

PowerInterfaceImpl

drivers/peripheral/power/interfaces/hdi_service/src/PowerInterfaceImpl.h

static constexpr const char * const SUSPEND_STATE = "mem";
static constexpr const char * const SUSPEND_STATE_PATH = "/sys/power/state";
static constexpr const char * const LOCK_PATH = "/sys/power/wake_lock";
static constexpr const char * const UNLOCK_PATH = "/sys/power/wake_unlock";
static constexpr const char * const WAKEUP_COUNT_PATH = "/sys/power/wakeup_count";
...
int32_t PowerInterfaceImpl::ForceSuspend()
{
    g_suspendRetry = false;

    NotifyCallback(CMD_ON_SUSPEND);
    g_powerState = PowerHdfState::SLEEP;
    //直接调用DoSuspend(),进行mem写入
    DoSuspend();
    g_powerState = PowerHdfState::AWAKE;
    NotifyCallback(CMD_ON_WAKEUP);

    StartSuspend();
    return HDF_SUCCESS;
}    
...  
int32_t PowerInterfaceImpl::StartSuspend()
{
    std::lock_guard<std::mutex> lock(g_mutex);
    g_suspendRetry = true;
    if (g_suspending) {
        g_powerState = PowerHdfState::INACTIVE;
        g_suspendCv.notify_one();
        return HDF_SUCCESS;
    }
    g_suspending = true;
    // 开启AutoSuspendLoop线程
    g_daemon = std::make_unique<std::thread>(&AutoSuspendLoop);
    g_daemon->detach();
    return HDF_SUCCESS;
}    

void AutoSuspendLoop()
{
    auto suspendLock = std::unique_lock(g_suspendMutex);
    while (true) {
        std::this_thread::sleep_for(waitTime_);
        /*
        1.读取wakeup count值,如果成功,将读取的值回写。若无值,continue。
        2.回写后,判断返回值是否成功,如果不成功继续写,直到成功。成功后,可以触发DoSuspend()。
        */
        const std::string wakeupCount = ReadWakeCount();
        if (wakeupCount.empty()) {
            continue;
        }
        if (!g_suspendRetry) {
            g_suspendCv.wait(suspendLock);
        }
        if (!WriteWakeCount(wakeupCount)) {
            continue;
        }

        NotifyCallback(CMD_ON_SUSPEND);
        g_powerState = PowerHdfState::SLEEP;
        DoSuspend();
        g_powerState = PowerHdfState::AWAKE;
        NotifyCallback(CMD_ON_WAKEUP);
    }
    g_suspending = false;
    g_suspendRetry = false;
}

// 挂起操作:用户态写入mem 至 "/sys/power/state"
int32_t DoSuspend()
{
    std::lock_guard<std::mutex> lock(g_mutex);
    UniqueFd suspendStateFd(TEMP_FAILURE_RETRY(open(SUSPEND_STATE_PATH, O_RDWR | O_CLOEXEC)));
    if (suspendStateFd < 0) {
        return HDF_FAILURE;
    }
    bool ret = SaveStringToFd(suspendStateFd, SUSPEND_STATE);
    if (!ret) {
        HDF_LOGE("DoSuspend fail");
        return HDF_FAILURE;
    }
    return HDF_SUCCESS;
}

// 回调可以用来进行suspend前的数据处理
void NotifyCallback(int code)
{
    if (g_callback == nullptr) {
        return;
    }
    switch (code) {
        case CMD_ON_SUSPEND:
            g_callback->OnSuspend();
            break;
        case CMD_ON_WAKEUP:
            g_callback->OnWakeup();
            break;
        default:
            break;
    }
}

总结

本文主要和大家分享了OpenHarmony电源管理子系统的power manager的Awake/Inactive/Sleep的过程,对 电源管理服务组件的息屏/休眠做了较为详细的代码说明,希望通过本文您能初步掌握电源管理子系统的power manager关键功能和核心流程。关于OpenHarmony其它子系统的分析,请关注后续文章。

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部