- 电源管理子系统
1.电源管理子系统概述
电源管理子系统是 OpenHarmony 的基本能力子系统,有电池服务组件、显示控制组件和电源管理服务组件,主要提供如下功能:
- 重启服务:系统重启和下电。
- 系统电源管理服务:系统电源状态管理和休眠运行锁管理。
- 显示相关的能耗调节:包括根据环境光调节背光亮度,和根据接近光亮灭屏。
- 省电模式 :在不损害主要功能和性能的前提下,提供一种低功耗操作模式 。
- 电池服务:支持充放电、电池和充电状态的监测,包括状态的更新和上报,还包括关机充电。
- 温控 :在设备温度到一定程度之后对应用、SoC、外设进行管控,限制温升 。
- 耗电统计: 主要包括软件耗电和硬件耗电统计,以及单个应用的耗电统计 。
- 轻设备电池服务。
- 轻设备电源管理服务。
1.1.电源管理子系统架构
电源管理子系统架构图:
目录结构如下:
c
/base/powermgr
├── battery_lite # 轻设备电池服务
├── battery_manager # 电池服务
├── battery_statistics # 耗电统计服务
├── display_manager # 显示能效管理服务
├── power_manager # 系统电源管理服务
├── powermgr_lite # 轻设备电源管理服务
└── thermal_manager # 温控和热管理服务
电源管理提供了七个子部件,其中部分部件提供了对外接口或者公共事件通知,开发者可以根据场景使用:
- Power Manager 提供的接口,可以进行申请和释放休眠运行锁 RunningLock、设置电源模式、重启设备、关机等操作,同时也可以通过公共事件来监听省电模式和关机状态的变化。
- Battery Manager 提供了电池信息查询的接口,同时开发者也可以通过公共事件监听电池状态和充放电状态的变化。
- Thermal Manager 提供的设备温升状态的查询接口,同时开发者也可以通过注册回调和公共事件来监听设备温升状态。
- Battery Statistics 提供了软硬件耗电统计的功能,可以查询硬件耗电或者应用耗电情况。
- Display Power Manager 提供了亮度设置接口。
1.2.电源管理模式
OH节能模式有两种状态:熄屏状态和休眠状态。电源管理子系统包括内核态以及用户态的相互协同工作。
-
内核对休眠的支持与相关流程如下:
- freeze: 冻结I/O设备,将它们置于低功耗状态,使处理器进入空闲状态,唤醒最快,耗电比其它standby, mem, disk方式高
- standby:除了冻结I/O设备外,还会暂停系统,唤醒较快,耗电比其它 mem, disk方式高
- mem: 将运行状态数据存到内存,并关闭外设,进入等待模式,唤醒较慢,耗电比disk方式高
- disk: 将运行状态数据存到硬盘,然后关机,唤醒最慢
-
用户态电源管理子系统电源模式:正常模式,省电模式,性能模式,超级省电。可通过配置文件对详细策略进行修改:
- base/powermgr/power_manager/services/native/profile/power_mode_config.xml
如下图,电源管理服务与电源管理服务相互协同管理屏幕亮息屏及通过UHDF对设备电源的状态切换。
2.电源服务组件
电源管理服务组件是 OpenHarmony 的电源管理子系统中的重要组件之一,主要提供如下功能:
- 重启系统。
- 管理休眠运行锁。
- 系统电源状态查询。
电源管理子系统之电源管理服务组件架构图:
代码目录:
c
/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 # 工具和通用层
2.1.电源管理策略
- OpenHarmony标准系统的统一电源管理策略配置,见 power_mode_config.xml (/base/powermgr/power_manager/services/native/profile/)文件,不同的配置对应不同的功耗情况。
c
17 <!--
18 Power Mode Definitions: // 电源模式定义
19 MODE_NORMAL = 600, // 正常模式
20 MODE_POWER_SAVE = 601, // 省电模式
21 MODE_PERFORMANCE = 602, // 性能优先
22 MODE_EXTREME_POWER_SAVE = 603,// 超级省电
23 -->
24 <!--
25 Action Definitions: // 行为定义
26 DisplayOffTime = 101, // 息屏时间控制
27 SystemAutoSleepTime = 102, // 系统自动睡眠时间控制
28 AutoAdjustBrightness = 103, // 亮度自动调整时间控制
29 AutoWindowRotation = 107, // 窗口自动旋转时间控制
30 SystemBrightness = 115, // 系统亮度调节
31 VibratorsState = 120, // 马达(震动)状态
32 -->
33 <switch_proxy version="1">
34 <proxy id="600">
<!-- value[单位:ms],-1表示不设置,如DisplayOffTime设为-1表示不息屏 -->
35 <switch id="101" value="30000" recover_flag="0"/>
36 <switch id="102" value="0" recover_flag="0"/>
37 <switch id="103" value="-1" recover_flag="0"/>
38 <switch id="107" value="1" recover_flag="0"/>
39 <switch id="115" value="102" recover_flag="0"/>
40 <switch id="120" value="1" recover_flag="0"/>
41 </proxy>
42 <proxy id="601">
43 <switch id="101" value="10000" recover_flag="0"/>
44 <switch id="102" value="5000" recover_flag="0"/>
45 <switch id="103" value="-1" recover_flag="0"/>
46 <switch id="107" value="-1" recover_flag="0"/>
47 <switch id="115" value="50" recover_flag="0"/>
48 <switch id="120" value="-1" recover_flag="0"/>
49 </proxy>
50 <proxy id="602">
51 <switch id="101" value="-1" recover_flag="0"/>
52 <switch id="102" value="-1" recover_flag="0"/>
53 <switch id="103" value="-1" recover_flag="0"/>
54 <switch id="107" value="1" recover_flag="0"/>
55 <switch id="115" value="255" recover_flag="0"/>
56 <switch id="120" value="1" recover_flag="0"/>
57 </proxy>
58 <proxy id="603">
59 <switch id="101" value="5000" recover_flag="0"/>
60 <switch id="102" value="1000" recover_flag="0"/>
61 <switch id="103" value="-1" recover_flag="0"/>
62 <switch id="107" value="-1" recover_flag="0"/>
63 <switch id="115" value="25" recover_flag="0"/>
64 <switch id="120" value="-1" recover_flag="0"/>
65 </proxy>
66 </switch_proxy>
备注:
修改电源管理策略参考:https://ost.51cto.com/posts/22630
- 唤醒源配置,见power_wakeup.json(base/powermgr/power_manager/services/native/profile/)
OpenHarmony支持多种唤醒源,如电源键、键盘、鼠标等,并提供了定制开启和关闭的方式。当设备进入休眠状态后,用户可以通过按电源键、按键盘、鼠标事件、轻触屏幕等,来点亮屏幕并唤醒设备。但不同的产品可能支持不同的外设,比如无手写笔、无皮套等。为此,OpenHarmony提供唤醒源的定制方式,产品可以根据具体的设计规格来定制此特性。
c
1 {
2 "powerkey": {
3 "enable": true //是否开启唤醒监听
4 },
5 "keyborad": {
6 "enable": true
7 },
8 "mouse": {
9 "enable": true
10 },
11 "touchscreen": {
12 "enable": true,
13 "click": 2 //点击次数
14 },
15 "touchpad": {
16 "enable": true
17 },
18 "pen": {
19 "enable": true
20 },
21 "lid": { //lid 皮套唤醒
22 "enable": true
23 },
24 "switch": { //switch 盖子唤醒
25 "enable": true
26 }
27 }
备注:
定制唤醒源参考:
https://www.seaxiang.com/blog/263c5f62883e453285ff757552c44a61
2.2.Power Manager Service 服务启动
源代码位置:
- base/powermgr/power_manager/services/native/src/power_state_machine.cpp
- base/powermgr/power_manager/services/native/src/power_mgr_service.cpp
2.2.1.Power Manager Service 注册
c
base/powermgr/power_manager/services/native/src/power_mgr_service.cpp:
auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
//调用SystemAbility接口注册PowerMgrService实例
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(pms.GetRefPtr());
//构建入参为serviceid、runoncreate
PowerMgrService::PowerMgrService() : SystemAbility(POWER_MANAGER_SERVICE_ID, true) {}
System Ability 管理模块调用 PowerMgrService 的启动函数实现电源管理服务组件的启动:
硬件上电后,电源管理服务被打包到 foundation 进程,将会进行 PowerMgrService 初始化。其中 powerStateMachine 也在 PowerMgrService 中进行初始化。详细启动流程看 System Ability 管理相关的资料。System Ability 管理模块调用 PowerMgrService 的启动函数 OnStart(),实现电源管理服务组件的启动。
2.2.2.Power Manager Service 启动
启动函数 OnStart() 最终分别通过调用 PowerStateMachine: Init()-> InitStateMap() 和 PowerStateMachine::InitState(),实现状态机的初始化和状态机的初态的设置。主要流程有:
-
调用 Init()函数,实现 PowerStateMachine 状态机的初始化;
-
调用 AddSystemAbilityListener(),监听依赖的服务,在 OnAddSystemAbility 中调用 RegisterBootCompletedCallback(),并根据具体的设备信息, 设置状态机的初始状态。
c
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
*/
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");
}
- PowerMgrService::Init()
调用PowerMgrService::PowerStateMachineInit(),对 PowerStateMachine 的初始化。
c
88 bool PowerMgrService::Init()
89 {
90 POWER_HILOGI(COMP_SVC, "Init start");
91 if (!runningLockMgr_) {
92 runningLockMgr_ = std::make_shared<RunningLockMgr>(pms);
93 }
94 if (!runningLockMgr_->Init()) {
95 POWER_HILOGE(COMP_SVC, "Running lock init fail");
96 return false;
97 }
98 if (!shutdownController_) {
99 shutdownController_ = std::make_shared<ShutdownController>();
100 }
// PowerStateMachine初始化 见下面
101 if (!PowerStateMachineInit()) {
102 POWER_HILOGE(COMP_SVC, "Power state machine init fail");
103 }
104
105 RegisterBootCompletedCallback();
106 POWER_HILOGI(COMP_SVC, "Init success");
107 return true;
108 }
137 bool PowerMgrService::PowerStateMachineInit()
138 {
139 if (powerStateMachine_ == nullptr) {
140 powerStateMachine_ = std::make_shared<PowerStateMachine>(pms);
// 调用powerStateMachine::Init()进行初始化状态机的所有状态及行为进行初始化
141 if (!(powerStateMachine_->Init())) {
142 POWER_HILOGE(COMP_SVC, "Power state machine start fail!");
143 return false;
144 }
145 }
146 if (powerMgrNotify_ == nullptr) {
147 powerMgrNotify_ = std::make_shared<PowerMgrNotify>();
148 powerMgrNotify_->RegisterPublishEvents();
149 }
150 return true;
151 }
- PowerStateMachine::Init():
通过 PowerStateMachine::InitStateMap(),实现对状态机的初始化。
c
base/powermgr/power_manager/services/native/src/power_state_machine.cpp:
71 bool PowerStateMachine::Init()
72 {
73 POWER_HILOGD(FEATURE_POWER_STATE, "Start init");
74
75 stateAction_ = PowerMgrFactory::GetDeviceStateAction();
//初始化状态机的多种状态:awake/inactive/sleep...
76 InitStateMap();
77
78 if (powerStateCBDeathRecipient_ == nullptr) {
79 powerStateCBDeathRecipient_ = new PowerStateCallbackDeathRecipient();
80 }
81 POWER_HILOGD(FEATURE_POWER_STATE, "Init success");
82 return true;
83 }
// 初始化状态机
void PowerStateMachine::InitStateMap()
{
EmplaceAwake(); // Awake
EmplaceFreeze(); // Freeze:TODO
EmplaceInactive(); // Inactive
EmplaceStandBy(); // StandBy:TODO
EmplaceDoze(); // Doze:TODO
EmplaceSleep(); // Sleep
EmplaceHibernate();// Hibernate:TODO
EmplaceShutdown(); // Shutdown:TODO
}
- EmplaceAwake()
调用公共函数 DeviceStateAction::SetDisplayState(...),设置 DisplayState 为 DISPLAY_ON 成功后,调用 ResetInactiveTimer(),开启 Inactive 倒计时。
c
base/powermgr/power_manager/services/native/src/power_state_machine.cpp:
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;
}));
}
- EmplaceInactive():
根据 enableDisplaySuspend_参数,传入 DISPLAY_OFF or DISPLAY_SUSPEND,调用公共函数 DeviceStateAction::SetDisplayState(...)。
c
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;
}
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;
}));
}
如上两个函数都调用公共函数 DeviceStateAction::SetDisplayState(...):
c
base\powermgr\power_manager\services\native\src\actions\default\display\device_state_action.cpp:
uint32_t DeviceStateAction::SetDisplayState(const DisplayState state, StateChangeReason reason)
{
// 若当前状态与待设置状态一致,则直接返回
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 = IsTimedOutWhileCoordinated(reason) ?
PowerStateChangeReason::STATE_CHANGE_REASON_COLLABORATION : static_cast<PowerStateChangeReason>(reason);
switch (state) {
case DisplayState::DISPLAY_ON: {
dispState = DisplayPowerMgr::DisplayState::DISPLAY_ON;
// 若当前为DisplayState::DISPLAY_OFF,则调用DisplayManager::WakeUpBegin(...),通知相关模块,进行唤醒流程。
if (currentState == DisplayState::DISPLAY_OFF) {
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;
}
最后调用DisplayPowerMgrClient::SetDisplayState():
c
base/powermgr/display_manager/state_manager/frameworks/native/display_power_mgr_client.cpp
// 这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxStub-->xxService
// 默认 uint32_t id = 0
87 bool DisplayPowerMgrClient::SetDisplayState(DisplayState state,
88 PowerMgr::StateChangeReason reason, uint32_t id)
89 {
90 auto proxy = GetProxy();
91 RETURN_IF_WITH_RET(proxy == nullptr, false);
92 return proxy->SetDisplayState(id, state, static_cast<uint32_t>(reason));
93 }
proxy->SetDisplayState 调用如下:
base/powermgr/display_manager/state_manager/service/native/src/display_power_mgr_service.cpp:
224 bool DisplayPowerMgrService::SetDisplayState(uint32_t id, DisplayState state, uint32_t reason)
225 {
226 if (!Permission::IsSystem()) {
227 return false;
228 }
// 根据id(默认为0),找到对应screenController
229 DISPLAY_HILOGI(COMP_SVC, "[UL_POWER] SetDisplayState %{public}d, %{public}d, %{public}u", id, state, reason);
230 auto iterator = controllerMap_.find(id);
231 if (iterator == controllerMap_.end()) {
232 if (id != DEFALUT_DISPLAY_ID) {
233 return false;
234 }
235 id = GetMainDisplayId();
236 iterator = controllerMap_.find(id);
237 if (iterator == controllerMap_.end()) {
238 return false;
239 }
240 }
241
242 BrightnessManager::Get().SetDisplayState(id, state, reason);
243 // 若是DISPLAY_OFF,则ScreenOffDelay
244 if (state == DisplayState::DISPLAY_OFF) {
245 if (!isDisplayDelayOff_) {
246 DISPLAY_HILOGI(COMP_SVC, "screen off immediately");
247 bool ret = iterator->second->UpdateState(state, reason);
248 if (!ret) {
249 DISPLAY_HILOGI(COMP_SVC, "[UL_POWER]undo brightness SetDisplayState");
250 BrightnessManager::Get().SetDisplayState(id, iterator->second->GetState(), reason);
251 }
252 return ret;
253 }
254 displayId_ = id;
255 displayState_ = state;
256 displayReason_ = reason;
257 FFRTTask task = [this]() { ScreenOffDelay(displayId_, displayState_, displayReason_); };
258 g_screenOffDelayTaskHandle = FFRTUtils::SubmitDelayTask(task, displayOffDelayMs_, queue_);
259 tempState_ = iterator->second->SetDelayOffState();
260 return true;
261 } else if (state == DisplayState::DISPLAY_ON) {
// 若是DISPLAY_ON,且isDisplayDelayOff_为真,则移除g_screenOffDelayTaskHandle
262 if (isDisplayDelayOff_) {
263 DISPLAY_HILOGI(COMP_SVC, "need remove delay task");
264 FFRTUtils::CancelTask(g_screenOffDelayTaskHandle, queue_);
265 isDisplayDelayOff_ = false;
266 tempState_ = iterator->second->SetOnState();
267 return true;
268 }
269 }
// 以上都不是,则 ScreenController::UpdateState
270 return iterator->second->UpdateState(state, reason);
271 }
2.2.4.PowerMgrService::RegisterBootCompletedCallback()
c
void PowerMgrService::RegisterBootCompletedCallback()
{
//初始化回调函数g_bootCompletedCallback
g_bootCompletedCallback = []() {
POWER_HILOGI(COMP_SVC, "BootCompletedCallback triggered");
auto power = DelayedSpSingleton<PowerMgrService>::GetInstance();
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的相关初始化
#ifdef POWER_MANAGER_POWER_DIALOG
power->GetShutdownDialog().LoadDialogConfig();
power->GetShutdownDialog().KeyMonitorInit();
#endif
#ifndef CONFIG_FACTORY_MODE
power->HallSensorSubscriberInit();
POWER_HILOGI(COMP_SVC, "Subscribe Hall sensor");
#else
POWER_HILOGI(COMP_SVC, "Disabled Hall sensor");
#endif
power->SwitchSubscriberInit();
power->InputMonitorInit();
power->SuspendControllerInit();
power->WakeupControllerInit();
#ifdef POWER_MANAGER_WAKEUP_ACTION
power->WakeupActionControllerInit();
#endif
power->VibratorInit();
isBootCompleted_ = true;
};
WakeupRunningLock::Create();
// 注册回调函数g_bootCompletedCallback至SysParam
SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
}
- powerStateMachine->InitState(): 根据当前的设备的状态信息,设置状态机的初态,调用状态设置函数SetState,即PowerStateMachine::SetState.
c
/base/powermgr/power_manager/services/native/src/power_state_machine.cpp
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);
}
}
- 调用PowerStateMachine::SetState 进行TransitTo状态转换,即调用PowerStateMachine::StateController::TransitTo
c
1723 bool PowerStateMachine::SetState(PowerState state, StateChangeReason reason, bool force)
1724 {
1725 POWER_HILOGD(FEATURE_POWER_STATE, "state=%{public}s, reason=%{public}s, force=%{public}d",
1726 PowerUtils::GetPowerStateString(state).c_str(), PowerUtils::GetReasonTypeString(reason).c_str(), force);
1727 std::lock_guard<std::mutex> lock(stateMutex_);
1732 ScreenChangeCheck timeoutCheck(ffrtTimer_, state, reason);
1733 SettingStateFlag flag(state, shared_from_this(), reason);
1738
1739 HandleProximityScreenOffTimer(state, reason);
1744
1745 std::shared_ptr<StateController> pController = GetStateController(state);
1751 if (IsTimeoutReason(reason) && forceTimingOut_.load()) {
1752 force = true;
1753 }
1754 UpdateSettingStateFlag(state, reason);
// TransitTo状态转换:PowerStateMachine::StateController::TransitTo
1755 TransitResult ret = pController->TransitTo(reason, force);
1756 timeoutCheck.Finish(ret);
1759 RestoreSettingStateFlag();
1760 return (ret == TransitResult::SUCCESS || ret == TransitResult::ALREADY_IN_STATE);
1761 }
2015 TransitResult PowerStateMachine::StateController::TransitTo(StateChangeReason reason, bool ignoreLock)
2016 {
2017 POWER_HILOGD(FEATURE_POWER_STATE, "Start");
2018 std::shared_ptr<PowerStateMachine> owner = owner_.lock();
2019 if (owner == nullptr) {
2020 POWER_HILOGW(FEATURE_POWER_STATE, "owner is nullptr");
2021 return TransitResult::OTHER_ERR;
2022 }
2023 POWER_HILOGI(FEATURE_POWER_STATE,
2024 "[UL_POWER] Transit from %{public}s to %{public}s for %{public}s ignoreLock=%{public}d",
2025 PowerUtils::GetPowerStateString(owner->currentState_).c_str(),
2026 PowerUtils::GetPowerStateString(this->state_).c_str(),
2027 PowerUtils::GetReasonTypeString(reason).c_str(), ignoreLock);
2028 MatchState(owner->currentState_, owner->stateAction_->GetDisplayState());
// 检查状态
2029 if (!CheckState()) {
2030 POWER_HILOGD(FEATURE_POWER_STATE, "Already in state: %{public}d", owner->currentState_);
2031 RecordFailure(owner->currentState_, reason, TransitResult::ALREADY_IN_STATE);
2032 return TransitResult::ALREADY_IN_STATE;
2033 }
2034
2035 if (reason != StateChangeReason::STATE_CHANGE_REASON_INIT && !owner->CanTransitTo(state_, reason)) {
2036 POWER_HILOGD(FEATURE_POWER_STATE, "Block Transit from %{public}s to %{public}s",
2037 PowerUtils::GetPowerStateString(owner->currentState_).c_str(),
2038 PowerUtils::GetPowerStateString(state_).c_str());
2039 RecordFailure(owner->currentState_, reason, TransitResult::FORBID_TRANSIT);
2040 return TransitResult::FORBID_TRANSIT;
2041 }
2042 // ignoreLock为true时,则不进行runningLock检测
2043 if (!ignoreLock && !owner->CheckRunningLock(GetState())) {
2044 POWER_HILOGD(FEATURE_POWER_STATE, "Running lock block");
2045 RecordFailure(owner->currentState_, reason, TransitResult::LOCKING);
2046 return TransitResult::LOCKING;
2047 }
// 进入相关状态的处理函数,详见PowerStateMachine::EmplaceXxx()
2048 TransitResult ret = action_(reason);
2049 if (ret == TransitResult::SUCCESS) {
2050 bool needNotify = NeedNotify(owner->currentState_);
2051 lastReason_ = reason;
2052 lastTime_ = GetTickCount();
2053 owner->currentState_ = GetState();
2054 if (needNotify) {
// 状态成功后,会调用NotifyPowerStateChanged(...),
2055 owner->NotifyPowerStateChanged(owner->currentState_, reason);
2056 }
2057 } else if (IsReallyFailed(reason)) {
2058 RecordFailure(owner->currentState_, reason, ret);
2059 }
2062 return ret;
2063 }
2.3.Awake流程分析
c
PowerStateMachine::InitState()
->SetState(PowerState::AWAKE, StateChangeReason::STATE_CHANGE_REASON_INIT, true);
-> PowerStateMachine::SetState
-> TransitResult ret = action_(reason);
-> PowerStateMachine::EmplaceAwake
由 PowerStateMachine::InitState(),直接调用 SetState(PowerState::AWAKE, StateChangeReason::STATE_CHANGE_REASON_INIT, true)进入 Awake 状态;最后调用PowerStateMachine::EmplaceAwake()函数,该函数主要进行两个步骤:
- 步骤 1:DeviceStateAction::SetDisplayState
调用 DeviceStateAction::SetDisplayState(DisplayState::DISPLAY_ON, reason); 看公共函数的 DISPLAY_ON 分支;
调用DisplayPowerMgrClient::SetDisplayState
c
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;
}
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));
}
...
224 bool DisplayPowerMgrService::SetDisplayState(uint32_t id, DisplayState state, uint32_t reason)
225 {
// 根据id(默认为0),找到对应screenController
229 DISPLAY_HILOGI(COMP_SVC, "[UL_POWER] SetDisplayState %{public}d, %{public}d, %{public}u", id, state, reason);
230 auto iterator = controllerMap_.find(id);
231 if (iterator == controllerMap_.end()) {
232 if (id != DEFALUT_DISPLAY_ID) {
233 return false;
234 }
235 id = GetMainDisplayId();
236 iterator = controllerMap_.find(id);
237 if (iterator == controllerMap_.end()) {
238 return false;
239 }
240 }
241
242 BrightnessManager::Get().SetDisplayState(id, state, reason);
243 // 若是DISPLAY_OFF,则ScreenOffDelay
244 if (state == DisplayState::DISPLAY_OFF) {
245 ...
260 return true;
261 } else if (state == DisplayState::DISPLAY_ON) {
// 若是DISPLAY_ON,且isDisplayDelayOff_为真,则移除g_screenOffDelayTaskHandle
262 if (isDisplayDelayOff_) {
263 DISPLAY_HILOGI(COMP_SVC, "need remove delay task");
264 FFRTUtils::CancelTask(g_screenOffDelayTaskHandle, queue_);
265 isDisplayDelayOff_ = false;
266 tempState_ = iterator->second->SetOnState();
267 return true;
268 }
269 }
// 以上都不是,则 ScreenController::UpdateState
270 return iterator->second->UpdateState(state, reason);
271 }
- 步骤 2:PowerStateMachine::ResetInactiveTimer
若配置文件中 DisplayOffTime>=0, 则开启 Inactive 计时。
c
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 任务。
c
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) {
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;
}
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;
}
}
}
- 2/3的DisplayOffTime后,调用 HandleActivityTimeout,即PowerStateMachine::HandleActivityTimeout
c
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() 具体的流程如下,即调用基类的 notify 方法。 通知对应的 Listener,设置状态为 Inactive。Listener 由 SuspendController::Init()初始化。
c
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_);
}
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
void SuspendController::Init()
{
...
}
- 根据action类型,调用不同的SuspendAction,比如:HandleAutoSleep(reason);
c
base/powermgr/power_manager/services/native/src/suspend/suspend_controller.cpp
583 void SuspendController::HandleAutoSleep(SuspendDeviceType reason)
584 {
// 设置状态为sleep
591 bool ret = stateMachine_->SetState(
592 PowerState::SLEEP, stateMachine_->GetReasonBySuspendType(reason));
593 if (ret) {
594 POWER_HILOGI(FEATURE_SUSPEND, "State changed, set sleep timer");
595 TriggerSyncSleepCallback(false);
596 SystemSuspendController::GetInstance().Suspend([]() {}, []() {}, false);
597 } else {
598 POWER_HILOGI(FEATURE_SUSPEND, "auto suspend: State change failed");
599 }
600 }
- 驱动部分实现具体的 sleep 的操作,即 suspend:
c
base/powermgr/power_manager/services/native/src/actions/default/system_suspend_controller.cpp
122 void SystemSuspendController::Suspend(
123 const std::function<void()>& onSuspend, const std::function<void()>& onWakeup, bool force)
124 {
125 POWER_HILOGI(COMP_SVC, "The hdf interface, force=%{public}u", static_cast<uint32_t>(force));
134 if (force) {
// 实现在PowerInterfaceImpl
135 powerInterface_->ForceSuspend();
136 } else if (allowSleepTask_.load()) {
137 powerInterface_->StartSuspend();
138 }
139 }
- PowerInterfaceImpl
函数 DoSuspend实现在休眠的关键动作,写入mem到/sys/power/state,让设备真正进入休眠状态。
c
drivers/peripheral/power/interfaces/hdi_service/src/PowerInterfaceImpl.h
int32_t PowerInterfaceImpl::ForceSuspend()
{
HDF_LOGI("force suspend");
{
std::lock_guard<std::mutex> lock(g_forceMutex);
g_forceSuspendStart = true;
g_suspendRetry = false;
}
NotifyCallback(CMD_ON_SUSPEND);
g_powerState = PowerHdfState::SLEEP;
//直接调用DoSuspend(),进行mem写入
DoSuspend();
g_powerState = PowerHdfState::AWAKE;
NotifyCallback(CMD_ON_WAKEUP);
std::lock_guard<std::mutex> lock(g_forceMutex);
if (g_forceSuspendStart) {
StartSuspend();
}
return HDF_SUCCESS;
}
drivers/peripheral/power/interfaces/hdi_service/power_interface_impl.cpp
// 挂起操作:用户态写入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;
}
/commonlibrary/c_utils/base/src/file_ex.cpp
231 bool SaveStringToFd(int fd, const std::string& content)
232 {
237
243 const ssize_t len = write(fd, content.c_str(), content.length());
248
249 if (static_cast<unsigned long>(len) != content.length()) {
250 UTILS_LOGE("the length write to file is not equal to fileLength!len:%{public}zd, fileLen:%{public}zu",
251 len, content.length());
252 return false;
253 }
254
255 return true;
256 }
refer to
- https://ost.51cto.com/posts/9420
- https://ost.51cto.com/posts/22630
- https://laval.csdn.net/64e42be0bbf5bc4f23624908.html
- https://forums.openharmony.cn/forum.php?mod=viewthread\&tid=616
- https://blog.csdn.net/HarmonyOS_666/article/details/140995131
- https://www.seaxiang.com/blog/263c5f62883e453285ff757552c44a61
- https://docs.openharmony.cn/pages/v4.1/zh-cn/device-dev/subsystems/subsys-power-mode-customization.md
- https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-power-wakeup-source-customization.md