#星光计划2.0# OpenHarmony 源码解析之电源管理子系统 原创 精华
作者:王奎
【本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0】
1 简介
电源管理子系统是OpenHarmony的基本能力子系统,有电池服务组件、显示控制组件和电源管理服务组件,主要提供如下功能:
- 重启系统。
- 管理休眠运行锁。
- 系统电源状态查询。
- 充电和电池状态查询和上报。
- 亮灭屏管理和亮度调节。
开发者通过电源管理子系统提供的接口可以进行申请和释放休眠运行锁RunningLock
、获取电池信息、亮度调节、重启设备、关机等操作。
本文重点分析电池服务组件、显示控制组件和电源管理服务组件发布的接口和关键流程代码。文中涉及到HDF
驱动框架、SystemAbility
框架等内容只是简单提及,没有做详细分析。
1.1 OpenHarmony架构图
1.2 电源管理子系统架构图
2 电池服务组件
电池服务组件提供如下功能:
- 电池信息查询。
- 充放电状态查询。
2.1 代码目录
base/powermgr/battery_manager
├── hdi # HDI层
│ ├── api # HDI接口
│ └── client # HDI客户端
│ └── service # HDI服务端
├── interfaces # 接口层
│ ├── innerkits # 内部接口
│ └── kits # 外部接口
├── sa_profile # SA配置文件
└── services # 服务层
│ ├── native # native层
│ └── zidl # zidl接口层
└── utils # 工具和通用层
2.2 电池和充电属性接口
batteryInfo
描述电池信息。
名称 | 读写属性 | 类型 | 描述 |
---|---|---|---|
batterySOC | 只读 | number | 表示当前设备剩余电池容量。 |
chargingStatus | 只读 | BatteryChargeState | 表示当前设备电池的充电状态。 |
healthStatus | 只读 | BatteryHealthState | 表示当前设备电池的健康状态。 |
pluggedType | 只读 | BatteryPluggedType | 表示当前设备连接的充电器类型。 |
voltage | 只读 | number | 表示当前设备电池的电压。 |
technology | 只读 | string | 表示当前设备电池的技术型号。 |
batteryTemperature | 只读 | number | 表示当前设备电池的温度。 |
BatteryPluggedType
表示连接的充电器类型的枚举。
名称 | 默认值 | 描述 |
---|---|---|
NONE | 0 | 表示连接充电器类型未知,或电源已拔下。 |
AC | 1 | 表示连接的充电器类型为交流充电器。 |
USB | 2 | 表示连接的充电器类型为USB。 |
WIRELESS | 3 | 表示连接的充电器类型为无线充电器。 |
BatteryChargeState
表示电池充电状态的枚举。
名称 | 默认值 | 描述 |
---|---|---|
NONE | 0 | 表示电池充电状态未知。 |
ENABLE | 1 | 表示电池充电状态为使能状态。 |
DISABLE | 2 | 表示电池充电状态为停止状态。 |
FULL | 3 | 表示电池充电状态为已充满状态。 |
BatteryHealthState
表示电池的健康状态的枚举。
名称 | 默认值 | 描述 |
---|---|---|
UNKNOWN | 0 | 表示电池健康状态未知。 |
GOOD | 1 | 表示电池健康状态为正常。 |
OVERHEAT | 2 | 表示电池健康状态为过热。 |
OVERVOLTAGE | 3 | 表示电池健康状态为过压。 |
COLD | 4 | 表示电池健康状态为低温。 |
DEAD | 5 | 表示电池健康状态为僵死状态。 |
2.3 Battery Service服务启动
Battery Service
服务被打包到foundation
进程。
System Ability
管理模块用于管理系统基础能力,本服务需要向该模块注册,如果没有编写profile
配置,则System Ability
管理模块在启动时不会注册该服务。详细启动流程可以看System Ability
管理相关的资料。
注册信息:
<systemability>
<name>3302</name>
<libpath>libbatteryservice.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Tips:
1.name:为对应的serviceId必须与代码中注册的serviceId保持一致;电池服务组件的serviceId为3302;
2.libpath:为SystemAbility的加载路径,必配项;
3.run-on-create:true表示进程启动后即向samgr组件注册该SystemAbility;false表示按需启动,即在其他模块访问到该SystemAbility时启动;必配项;
4.distributed:true表示该SystemAbility为分布式SystemAbility,支持跨设备访问;false表示只有本地跨IPC访问;
5.dump-level:表示systemdumper支持的level等级,默认配置1就OK;
6.注册信息配置文件:/system/profile/foundation.xml
注册代码:
//调用SystemAbility接口注册BatteryService实例
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(
DelayedSpSingleton<BatteryService>::GetInstance().GetRefPtr());
//构建入参为serviceid、runoncreate
BatteryService::BatteryService()
: SystemAbility(POWER_MANAGER_BATT_SERVICE_ID, true) {}
System Ability管理模块调用BatteryService
的启动函数实现电池服务组件的启动:
void BatteryService::OnStart()
{
POWER_HILOGI(MODULE_BATT_SERVICE, "OnStart enter");
//如果已启动则返回(BatteryService是单实例服务,只会启动一个)
if (ready_) {
POWER_HILOGE(MODULE_BATT_SERVICE, "OnStart is ready, nothing to do");
return;
}
//创建BatterysrvEventHandler实例
//等待CommonEventService服务启动完成之后初始化完成
if (!(Init())) {
POWER_HILOGE(MODULE_BATT_SERVICE, "OnStart call init fail");
return;
}
//创建BatteryServiceSubscriber类实例,用于处理Battery Deamon服务进程(batteryd)发来的订阅消息
//向batteryd发送绑定消息,订阅Battery相关消息
if (!(InitBatteryd())) {
POWER_HILOGE(MODULE_BATT_SERVICE, "OnStart call initBatteryd fail");
return;
}
//BatteryService服务发布到System Ability管理模块
if (!Publish(this)) {
POWER_HILOGE(MODULE_BATT_SERVICE, "OnStart register to system ability manager failed!");
return;
}
ready_ = true; //设置已启动
POWER_HILOGI(MODULE_BATT_SERVICE, "OnStart and add system ability success");
}
2.4 Battery Deamon(batteryd)启动
batteryd是HDI(即驱动接口)层服务,打包在power_host进程。本文的代码分析不包括驱动程序框架的完整驱动加载过程,主要分析batteryd的实现。
驱动程序 (Driver Entry)入口中的三个主要接口:
- Bind 接口:实现驱动接口实例化绑定,如果需要发布驱动接口,会在驱动加载过程中被调用,实例化该接口的驱动服务并和 DeviceObject 绑定。
- Init 接口:实现驱动的初始化,返回错误将中止驱动加载流程。
- Release 接口:实现驱动的卸载,在该接口中释放驱动实例的软硬件资源。
实现batteryd驱动程序初始化接口:
struct HdfDriverEntry g_batterydEntry = {
.moduleVersion = 1,
.moduleName = "batteryd",
.Bind = BatterydBind,
.Init = BatterydInit,
.Release = BatterydRelease,
};
HDF_INIT(g_batterydEntry); //宏声明导出驱动程序入口,驱动框架启动时查找到moduleName = "batteryd",则按照入口信息启动batteryd的服务。
static int32_t BatterydBind(struct HdfDeviceObject *device)
{
HDF_LOGD("%{public}s enter", __func__);
struct BatterydService *service = NULL;
if (device == NULL) {
HDF_LOGW("%{public}s device is NULL", __func__);
return HDF_ERR_INVALID_OBJECT;
}
service = (struct BatterydService *)OsalMemCalloc(sizeof(*service));
if (service == NULL) {
HDF_LOGE("%{public}s: calloc address error", __func__);
return HDF_ERR_MALLOC_FAIL;
}
//IO Service 完成 IPC 通信的客户端消息请求封装,IO Dispatcher 完成驱动服务端消息请求封装
//客户端消息通过 IPC 通信到达服务端并分发给 IO Dispatcher 处理。
service->device = device;
service->ioService.Dispatch = BatterydDispatch; //此处绑定了BatterydDispatch作为消息处理函数。
device->service = &(service->ioService);
return HDF_SUCCESS;
}
static int32_t BatterydInit(struct HdfDeviceObject *device)
{
HDF_LOGD("%{public}s enter", __func__);
int32_t ret;
if (device == NULL || device->service == NULL) {
HDF_LOGW("%{public}s device or device->service is NULL", __func__);
return HDF_ERR_INVALID_OBJECT;
}
struct BatterydService *service = (struct BatterydService *)device->service;
if (service == NULL) {
HDF_LOGE("%{public}s get batteryd service failed", __func__);
return HDF_ERR_INVALID_OBJECT;
}
//读取/sys/class/power_supply目录下的文件信息初始化capacity、voltage、temperature、healthState、status、present等文件路径。
ret = InitBatterydSysfs();
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s init batteryd sysfs failed, ret: %{public}d", __func__, ret);
return ret;
}
//创建一个套接字,并绑定到batteryd的pid,用于从内核接收消息。
//地址族:Address Family AF_NETLINK
//协议号:NETLINK_KOBJECT_UEVENT
//数据传输方式:SOCK_DGRAM | SOCK_CLOEXEC
ret = InitUevent(service);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s init uevent failed, ret: %{public}d", __func__, ret);
return ret;
}
//创建并启动接收接收消息的线程
//处理消息中的batteryInfo信息,读取并处理batteryinfo相关数据。
//发送CMD_NOTIFY_SUBSCRIBER消息,BatterydSubscriber::OnRemoteRequest处理该消息,解析batteryinfo。
//并调用BatteryServiceSubscriber::Update方法发布公共事件消息
//COMMON_EVENT_BATTERY_CHANGED(即:usual.event.BATTERY_CHANGED)。
//APP可以处理此消息,响应电池管理模块发送的batteryinfo更新信息。
ret = StartLoopingThread(service);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s start loop thread failed, ret: %{public}d", __func__, ret);
return ret;
}
return ret;
}
//释放BatterydService
static void BatterydRelease(struct HdfDeviceObject *device)
{
HDF_LOGD("%{public}s enter", __func__);
if (device == NULL) {
return;
}
struct BatterydService *service = (struct BatterydService *)device->service;
if (service == NULL) {
HDF_LOGW("%{public}s batteryd service is NULL, no need to release", __func__);
return;
}
OsalMemFree(service);
}
实现驱动程序初始化后,需要将驱动程序入口通过驱动声明宏导出,这样驱动框架才能在启动时识别到驱动程序的存在,驱动才能被加载:
#define HDF_INIT(module) HDF_DRIVER_INIT(module)
这里将 HDF_INIT 宏展开:
#define USED_ATTR __attribute__((used))
#define HDF_SECTION __attribute__((section(".hdf.driver")))
#define HDF_DRIVER_INIT(module) \
const size_t USED_ATTR module##HdfEntry HDF_SECTION = (size_t)(&(module))
2.5 电池batteryInfo信息查询流程
以获取当前设备剩余电池容量(batterySOC)为例,下面为完整处理流程:
流程图:
代码:
//导入模块
import batteryInfo from '@ohos.batteryInfo';
//调用batterySOC查询接口
var batterySoc = batteryInfo.batterySOC;
//注册在动态库中的BatterySOC接口,实现了电池容量的查询
static napi_value BatterySOC(napi_env env, napi_callback_info info)
{
napi_value napiValue = nullptr;
int32_t capacity = g_battClient.GetCapacity();
NAPI_CALL(env, napi_create_int32(env, capacity, &napiValue));
POWER_HILOGD(MODULE_JS_NAPI, "capacity %{public}d", capacity);
return napiValue;
}
//上面接口调用g_battClient.GetCapacity()
int32_t BatterySrvClient::GetCapacity()
{
int32_t capacity = INVALID_BATT_INT_VALUE;
//查找到到POWER_MANAGER_BATT_SERVICE_ID(即BatteryService)服务并赋值给proxy_
//这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxServiceStub-->xxService。
RETURN_IF_WITH_RET(Connect() != ERR_OK, capacity);
//调用BatteryService::GetCapacity()
capacity = proxy_->GetCapacity();
POWER_HILOGI(MODULE_BATT_INNERKIT, " Calling GetCapacity Success!");
return capacity;
}
int32_t BatteryService::GetCapacity()
{
return BatterydClient::GetCapacity();
}
int32_t BatterydClient::GetCapacity()
{
POWER_HILOGD(MODULE_BATTERYD, "GetCapacity enter");
MessageParcel data;
MessageParcel reply;
//向batteryd发送CMD_GET_CAPACITY消息
ErrCode ret = DoDispatch(CMD_GET_CAPACITY, data, reply);
if (FAILED(ret)) {
POWER_HILOGW(MODULE_BATTERYD, "CMD_GET_CAPACITY failed, return INVALID_BATT_INT_VALUE");
return INVALID_BATT_INT_VALUE;
}
int32_t capacity = reply.ReadInt32();
return capacity;
}
ErrCode BatterydClient::DoDispatch(uint32_t cmd, MessageParcel &data, MessageParcel &reply)
{
POWER_HILOGD(MODULE_BATTERYD, "Start to dispatch cmd: %{public}d", cmd);
//查找到batteryd服务
auto batteryd = GetBatterydService();
if (batteryd == nullptr) {
return ERR_NO_INIT;
}
MessageOption option;
//向batteryd server发送CMD_GET_CAPACITY消息,根据上面驱动注册的batteryd模块,会在BatterydDispatch接口处理该消息。
//这里涉及到HDF开发的知识,参见上面Battery Deamon启动。
auto ret = batteryd->SendRequest(cmd, data, reply, option);
if (ret != ERR_OK) {
POWER_HILOGE(MODULE_BATTERYD, "failed to send request, cmd: %{public}d, ret: %{public}d", cmd, ret);
return ret;
}
return ERR_OK;
}
int32_t BatterydDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
{
HDF_LOGD("%{public}s enter", __func__);
if (client == NULL || client->device == NULL) {
HDF_LOGE("%{public}s: client or client->device is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
struct BatterydService *service = (struct BatterydService *)client->device->service;
if (service == NULL) {
HDF_LOGE("%{public}s: service is NULL", __func__);
return HDF_FAILURE;
}
switch (cmdId) {
case CMD_BIND_BATTERY_SUBSCRIBER: {
return DispatchBindBatterySubscriber(service, data);
}
case CMD_UNBIND_BATTERY_SUBSCRIBER: {
return DispatchUnbindBatterySubscriber(service);
}
//处理CMD_GET_CAPACITY消息
case CMD_GET_CAPACITY: {
return DispatchGetCapacity(reply);
}
case CMD_GET_VOLTAGE: {
return DispatchGetVoltage(reply);
}
case CMD_GET_TEMPERATURE: {
return DispatchGetTemperature(reply);
}
case CMD_GET_HEALTH_STATE: {
return DispatchGetHealthState(reply);
}
case CMD_GET_PLUGGED_TYPE: {
return DispatchGetPluggedType(reply);
}
case CMD_GET_CHARGE_STATE: {
return DispatchGetChargeState(reply);
}
case CMD_GET_PRESENT: {
return DispatchGetPresent(reply);
}
case CMD_GET_TECHNOLOGY: {
return DispatchGetTechnology(reply);
}
default: {
HDF_LOGE("%{public}s: invalid cmdId %{public}d", __func__, cmdId);
return HDF_FAILURE;
}
}
}
static int32_t DispatchGetCapacity(struct HdfSBuf *reply)
{
int32_t ret;
int32_t capacity = 0;
//读取并解析capacity数据
ret = ParseCapacity(&capacity);
if (ret != HDF_SUCCESS) {
return ret;
}
HdfSbufWriteInt32(reply, capacity);
return HDF_SUCCESS;
}
int32_t ParseCapacity(int32_t *capacity)
{
int32_t ret;
int32_t value;
char buf[MAX_BUFF_SIZE] = {0};
//从capacity的系统文件读取当前设备剩余电池容量。
ret = ReadBatterySysfsToBuff(g_batterySysfsInfo.capacityPath, buf, sizeof(buf));
if (ret != HDF_SUCCESS) {
return ret;
}
//把读出的数据转为10进制
value = ParseInt(buf);
HDF_LOGD("%{public}s: capacity is %{public}d", __func__, value);
*capacity = value;
return HDF_SUCCESS;
}
2.6 电池batteryinfo信息变更发布流程
//在Battery Deamon启动初始化阶段启动了本线程,用于处理kernel发来的消息
static int LoopingThreadEntry(void *arg)
{
int32_t len;
char msg[UEVENT_MSG_LEN + UEVENT_RESERVED_SIZE] = {0};
struct BatterydService *service = (struct BatterydService *)arg;
HDF_LOGD("%{public}s enter, start batteryd looping", __func__);
while (true) {
do {
len = recv(service->ueventFd, msg, UEVENT_MSG_LEN, 0);
if (len < 0 || len >= UEVENT_MSG_LEN) {
HDF_LOGD("%{public}s recv return msg is invalid, len: %{public}d", __func__, len);
continue;
}
// msg separator
msg[len] = '\0';
msg[len + 1] = '\0';
if (!IsPowerSupplyEvent(msg)) {
continue;
}
struct BatterydInfo *batteryInfo = (struct BatterydInfo *)OsalMemCalloc(sizeof(*batteryInfo));
if (batteryInfo == NULL) {
HDF_LOGE("%{public}s: calloc battery info error", __func__);
continue;
}
ParseUeventToBatterydInfo(msg, batteryInfo);//处理更新的电池状态信息
NotifySubscriber(service->subscriber, batteryInfo);//向绑定的BatteryServiceSubscriber发送订阅的电池状态变更消息。
OsalMemFree(batteryInfo);
} while (len > 0);
HDF_LOGD("%{public}s recv error, len: %{public}d", __func__, len);
}
}
//处理更新的电池状态信息
void ParseUeventToBatterydInfo(const char *msg, struct BatterydInfo *info)
{
info->technology_ = "";
while (*msg) {
//遍历msg,找到消息对应的处理函数
for (int i = 0; g_batteryAssigners[i].prefix; ++i) {
if (!strncmp(msg, g_batteryAssigners[i].prefix, g_batteryAssigners[i].prefixLen)) {
HDF_LOGD("%{public}s: msg: %{public}s", __func__, msg);
msg += g_batteryAssigners[i].prefixLen;
g_batteryAssigners[i].Assigner(msg, info);
break;
}
}
while (*msg++) {} // move to next
}
info->pluggedType_ = PLUGGED_TYPE_NONE;
ParsePluggedType(&info->pluggedType_);
info->pluggedMaxCurrent_ = INVALID_BATT_INT_VALUE;
ParsePluggedMaxCurrent(&info->pluggedMaxCurrent_);
info->pluggedMaxVoltage_ = INVALID_BATT_INT_VALUE;
ParsePluggedMaxVoltage(&info->pluggedMaxVoltage_);
}
//上面变更消息的处理函数在此处注册
static struct BatteryAssigner g_batteryAssigners[] = {
{BATTERY_KEY_CAPACITY, sizeof(BATTERY_KEY_CAPACITY) - 1, CapacityAssigner},
{BATTERY_KEY_VOLTAGE, sizeof(BATTERY_KEY_VOLTAGE) - 1, VoltageAssigner},
{BATTERY_KEY_TEMPERATURE, sizeof(BATTERY_KEY_TEMPERATURE) - 1, TemperatureAssigner},
{BATTERY_KEY_HEALTH, sizeof(BATTERY_KEY_HEALTH) - 1, HealthStateAssigner},
{BATTERY_KEY_CHARGE_STATUS, sizeof(BATTERY_KEY_CHARGE_STATUS) - 1, ChargeStateAssigner},
{BATTERY_KEY_PRESENT, sizeof(BATTERY_KEY_PRESENT) - 1, PresentAssigner},
{BATTERY_KEY_TECHNOLOGY, sizeof(BATTERY_KEY_TECHNOLOGY) - 1, TechnologyAssigner},
{BATTERY_KEY_CHARGE_COUNTER, sizeof(BATTERY_KEY_CHARGE_COUNTER) - 1, ChargeCounterAssigner},
{NULL, 0, NULL} // end of the array
};
//电池剩余容量变更的处理函数(例)
inline static void CapacityAssigner(const char *str, struct BatterydInfo *info)
{
info->capacity_ = ParseInt(str); // default in percent format
}
//向绑定的BatteryServiceSubscriber发送订阅的电池状态变更消息。
void NotifySubscriber(const struct BatterydSubscriber *subscriber, const struct BatterydInfo *batteryInfo)
{
HDF_LOGD("%{public}s: enter", __func__);
if (subscriber == NULL) {
HDF_LOGD("%{public}s: subscriber is NULL", __func__);
return;
}
int ret;
struct HdfRemoteService *service = subscriber->remoteService;//BatteryService启动时会向batteryd注册订阅消息。
struct HdfSBuf *data = HdfSBufTypedObtain(SBUF_IPC);
struct HdfSBuf *reply = HdfSBufTypedObtain(SBUF_IPC);
if (data == NULL || reply == NULL) {
HDF_LOGE("%{public}s failed to obtain hdf sbuf", __func__);
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return;
}
HDF_LOGD("%{public}s BatteryInfo: capacity=%{public}d, voltage=%{public}d, temperature=%{public}d, " \
"healthState=%{public}d, pluggedType=%{public}d, pluggedMaxCurrent=%{public}d, " \
"pluggedMaxVoltage=%{public}d, chargeState=%{public}d, chargeCounter=%{public}d, present=%{public}d, " \
"technology=%{public}s", __func__, batteryInfo->capacity_, batteryInfo->voltage_,
batteryInfo->temperature_, batteryInfo->healthState_, batteryInfo->pluggedType_,
batteryInfo->pluggedMaxCurrent_, batteryInfo->pluggedMaxVoltage_, batteryInfo->chargeState_,
batteryInfo->chargeCounter_, batteryInfo->present_, batteryInfo->technology_);
HdfSbufWriteInt32(data, batteryInfo->capacity_);
HdfSbufWriteInt32(data, batteryInfo->voltage_);
HdfSbufWriteInt32(data, batteryInfo->temperature_);
HdfSbufWriteInt32(data, batteryInfo->healthState_);
HdfSbufWriteInt32(data, batteryInfo->pluggedType_);
HdfSbufWriteInt32(data, batteryInfo->pluggedMaxCurrent_);
HdfSbufWriteInt32(data, batteryInfo->pluggedMaxVoltage_);
HdfSbufWriteInt32(data, batteryInfo->chargeState_);
HdfSbufWriteInt32(data, batteryInfo->chargeCounter_);
HdfSbufWriteInt8(data, batteryInfo->present_);
HdfSbufWriteString(data, batteryInfo->technology_);
//向BatterydSubscriber发送订阅消息CMD_NOTIFY_SUBSCRIBER
ret = service->dispatcher->Dispatch(service, CMD_NOTIFY_SUBSCRIBER, data, reply);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%{public}s failed to notify subscriber, ret: %{public}d", __func__, ret);
} else {
HDF_LOGD("%{public}s: succeed to notify subscriber", __func__);
}
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
}
//该接口响应并处理订阅消息CMD_NOTIFY_SUBSCRIBER
int BatterydSubscriber::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
switch (code) {
case CMD_NOTIFY_SUBSCRIBER: {
const BatteryInfo &info = ParserBatteryInfo(data, reply, option);
return Update(info);//这里调用的时BatteryServiceSubscriber::Update()
}
default: {
POWER_HILOGW(MODULE_BATTERYD, "no specific cmd for code: %{public}d", code);
return ERR_INVALID_OPERATION;
}
}
}
//处理BatteryInfo的Builder处理
const BatteryInfo &BatterydSubscriber::ParserBatteryInfo(MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
auto builder = std::make_shared<BatteryInfo::Builder>();
auto *info = builder->SetCapacity(data.ReadInt32())
->SetVoltage(data.ReadInt32())
->SetTemperature(data.ReadInt32())
->SetHealthState((BatteryHealthState)data.ReadInt32())
->SetPluggedType((BatteryPluggedType)data.ReadInt32())
->SetPluggedMaxCurrent(data.ReadInt32())
->SetPluggedMaxVoltage(data.ReadInt32())
->SetChargeState((BatteryChargeState)data.ReadInt32())
->SetChargeCounter(data.ReadInt32())
->SetPresent((bool)data.ReadInt8())
->SetTechnology(data.ReadCString())
->Build();
return *info;
}
//发布电池状态变更的公共事件:COMMON_EVENT_BATTERY_CHANGED
int32_t BatteryServiceSubscriber::Update(const BatteryInfo &info)
{
POWER_HILOGD(MODULE_BATT_SERVICE, "BatteryInfo: capacity=%{public}d, voltage=%{public}d, " \
"temperature=%{public}d, healthState=%{public}d, pluggedType=%{public}d, " \
"pluggedMaxCurrent=%{public}d, pluggedMaxVoltage=%{public}d, " \
"chargeState=%{public}d, chargeCounter=%{public}d, present=%{public}d, " \
"technology=%{public}s",
info.GetCapacity(), info.GetVoltage(), info.GetTemperature(), info.GetHealthState(),
info.GetPluggedType(), info.GetPluggedMaxCurrent(), info.GetPluggedMaxVoltage(), info.GetChargeState(),
info.GetChargeCounter(), info.IsPresent(), info.GetTechnology().c_str());
bool ret = HandleBatteryChangedEvent(info);
return ret ? ERR_OK : ERR_NO_INIT;
}
bool BatteryServiceSubscriber::HandleBatteryChangedEvent(const BatteryInfo &info)
{
Want want;
want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED);
CommonEventData data;
data.SetWant(want);
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_CAPACITY);
data.SetData(ToString(info.GetCapacity()));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_VOLTAGE);
data.SetData(ToString(info.GetVoltage()));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_TEMPERATURE);
data.SetData(ToString(info.GetTemperature()));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_HEALTH_STATE);
data.SetData(ToString(static_cast<uint32_t>(info.GetHealthState())));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_PLUGGED_TYPE);
data.SetData(ToString(static_cast<uint32_t>(info.GetPluggedType())));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_PLUGGED_MAX_CURRENT);
data.SetData(ToString(info.GetPluggedMaxCurrent()));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_PLUGGED_MAX_VOLTAGE);
data.SetData(ToString(info.GetPluggedMaxVoltage()));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_CHARGE_STATE);
data.SetData(ToString(static_cast<uint32_t>(info.GetChargeState())));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_CHARGE_COUNTER);
data.SetData(ToString(info.GetChargeCounter()));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_PRESENT);
data.SetData(ToString(info.IsPresent()));
data.SetCode(BatteryInfo::COMMON_EVENT_CODE_TECHNOLOGY);
data.SetData(info.GetTechnology());
CommonEventPublishInfo publishInfo;
publishInfo.SetOrdered(true);
bool isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
if (!isSuccess) {
POWER_HILOGD(MODULE_BATT_SERVICE, "failed to publish BATTERY_CHANGED event");
}
return isSuccess;
}
3 显示控制组件
显示管理组件主要负责显示屏的亮/灭、亮度调节等功能,如下:
- 显示屏的亮/灭。
- 显示屏亮度调节。
3.1 代码目录
base/powermgr/display_manager
├── interfaces # 接口层
│ ├── innerkits # 内部接口
│ └── kits # 外部接口
├── sa_profile # SA配置文件
├── services # 服务层
│ ├── native # Native层
│ └── zidl # zidl层
└── utils # 工具和通用层
3.2 设置屏幕亮度接口
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
value | number | 是 | 亮度的值(0~255) |
示例:
import brightness from '@ohos.brightness.d.ts'
brightness.setValue(128);
3.3 Display Manager Service服务启动
Display Manager Service服务被打包到foundation进程,启动过程基本同电池服务(Battery Service)的启动,详细启动流程可以看System Ability管理相关的资料。
注册信息:
<systemability>
<name>3308</name>
<libpath>libdisplaymgrservice.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
注册代码:
REGISTER_SYSTEM_ABILITY_BY_ID(DisplaySystemAbility, DISPLAY_MANAGER_SERVICE_ID, true);
//宏定义展开,调用SystemAbility接口注册BatteryService实例
#define REGISTER_SYSTEM_ABILITY_BY_ID(abilityClassName, systemAbilityId, runOnCreate) \
const bool abilityClassName##_##RegisterResult = \
SystemAbility::MakeAndRegisterAbility(new abilityClassName(systemAbilityId, runOnCreate));
System Ability管理模块调用DisplaySystemAbility的启动函数实现显示控制服务组件的启动:
void OnStart() override
{
DISPLAY_HILOGI(MODULE_SERVICE, "Start service");
//此处与电池管理服务不同,是把DisplayMgrService的对象实例发布到System Ability管理模块
//所以客户端根据服务ID:DISPLAY_MANAGER_SERVICE_ID查到的是DisplayMgrService实例
service_ = new DisplayMgrService();
if (!Publish(service_)) {
DISPLAY_HILOGE(MODULE_SERVICE, "Failed to publish service");
}
}
//DisplayMgrService有private成员screenController_,其构造函数会进行ScreenAction::Init()
class DisplayMgrService : public DisplayMgrStub {
public:
bool SetScreenState(ScreenState state) override;
bool SetBrightness(int32_t value) override;
int32_t Dump(int32_t fd, const std::vector<std::u16string>& args) override;
private:
ScreenController screenController_;
};
ScreenController::ScreenController()
{
action_.Init();
}
//ScreenAction初始化函数
void ScreenAction::Init()
{
DeviceFuncs *f = NULL;
//查出设备的接口函数,其中包括Display相关接口
int32_t ret = DeviceInitialize(&f);
if (ret != DISPLAY_SUCCESS) {
DISPLAY_HILOGE(MODULE_SERVICE, "Failed to init device");
return;
}
hdiFuncs_ = DeviceFuncPtr(f);
DISPLAY_HILOGI(MODULE_SERVICE, "Succeed to init");
}
int32_t DeviceInitialize(DeviceFuncs **funcs)
{
DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in funcs is null"));
DeviceFuncs *dFuncs = (DeviceFuncs *)calloc(1, sizeof(DeviceFuncs));
DISPLAY_CHK_RETURN((dFuncs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not calloc"));
dFuncs->RegHotPlugCallback = RegHotPlugCallback;
dFuncs->GetDisplayCapability = GetDisplayCapability;
dFuncs->GetDisplaySuppportedModes = GetDisplaySuppportedModes;
dFuncs->GetDisplayMode = GetDisplayMode;
dFuncs->SetDisplayMode = SetDisplayMode;
dFuncs->GetDisplayPowerStatus = GetDisplayPowerStatus;
dFuncs->SetDisplayPowerStatus = SetDisplayPowerStatus;
dFuncs->PrepareDisplayLayers = PrepareDisplayLayers;
dFuncs->GetDisplayBacklight = GetDisplayBacklight;
dFuncs->SetDisplayBacklight = SetDisplayBacklight;
dFuncs->GetDisplayProperty = GetDisplayProperty;
dFuncs->GetDisplayCompChange = GetDisplayCompChange;
dFuncs->SetDisplayClientCrop = SetDisplayClientCrop;
dFuncs->SetDisplayClientDestRect = SetDisplayClientDestRect;
dFuncs->SetDisplayClientBuffer = SetDisplayClientBuffer;
dFuncs->SetDisplayClientDamage = SetDisplayClientDamage;
dFuncs->SetDisplayVsyncEnabled = SetDisplayVsyncEnabled;
dFuncs->RegDisplayVBlankCallback = RegDisplayVBlankCallback;
dFuncs->GetDisplayReleaseFence = GetDisplayReleaseFence;
dFuncs->CreateVirtualDisplay = CreateVirtualDisplay;
dFuncs->DestroyVirtualDisplay = DestroyVirtualDisplay;
dFuncs->SetVirtualDisplayBuffer = SetVirtualDisplayBuffer;
dFuncs->SetDisplayProperty = SetDisplayProperty;
dFuncs->Commit = Commit;
*funcs = dFuncs;
DISPLAY_LOGD("%{public}s: device initialize success", __func__);
HdiSession::GetInstance();
return DISPLAY_SUCCESS;
}
3.4 设置屏幕亮度流程
流程图:
代码:
//brightness.setValue接口是异步执行
static napi_value SetValue(napi_env env, napi_callback_info info)
{
DISPLAY_HILOGD(MODULE_JS_NAPI, "enter");
size_t argc = 1;
napi_value args[1] = { 0 };
napi_value jsthis;
void *data = nullptr;
napi_status status = napi_get_cb_info(env, info, &argc, args, &jsthis, &data);
NAPI_ASSERT(env, (status == napi_ok) && (argc >= 1), "Failed to get cb info");
//判断入参类型是否为number
napi_valuetype type;
NAPI_CALL(env, napi_typeof(env, args[0], &type));
NAPI_ASSERT(env, type == napi_number, "Wrong argument type. Numbers expected.");
//把读取数值入参转为int32类型
int32_t value = 0;
NAPI_CALL(env, napi_get_value_int32(env, args[0], &value));
BrightnessAsyncCallbackInfo* asyncCallbackInfo = new BrightnessAsyncCallbackInfo {
.env = env,
.asyncWork = nullptr,
};
asyncCallbackInfo->value = value;
napi_value resourceName;
napi_create_string_latin1(env, "setValue", NAPI_AUTO_LENGTH, &resourceName);
//创建异步执行任务
napi_create_async_work(
env,
nullptr,
resourceName,
[](napi_env env, void *data) {
BrightnessAsyncCallbackInfo* asyncCallbackInfo = (BrightnessAsyncCallbackInfo *)data;
//调用DisplayManager::SetBrightness设置屏幕亮度
if (!DisplayManager::SetBrightness(asyncCallbackInfo->value)) {
DISPLAY_HILOGE(MODULE_JS_NAPI, "Failed to set brightness");
} else {
DISPLAY_HILOGD(MODULE_JS_NAPI, "Succeed to set brightness");
}
},
[](napi_env env, napi_status status, void *data) {
BrightnessAsyncCallbackInfo* asyncCallbackInfo = (BrightnessAsyncCallbackInfo *)data;
napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
delete asyncCallbackInfo;
},
(void *)asyncCallbackInfo,
&asyncCallbackInfo->asyncWork);
//执行异步任务
NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork));
DISPLAY_HILOGD(MODULE_JS_NAPI, "return");
return nullptr;
}
bool DisplayManager::SetBrightness(int32_t value)
{
return DisplayMgrClient::GetInstance().SetBrightness(value);
}
bool DisplayMgrClient::SetBrightness(int32_t value)
{
//这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxServiceStub-->xxService。
//根据DISPLAY_MANAGER_SERVICE_ID查到DisplayMgrService服务能力
auto proxy = GetProxy();
if (proxy == nullptr) {
return false;
}
return proxy->SetBrightness(value);//调用DisplayMgrService::SetBrightness
}
bool DisplayMgrService::SetBrightness(int32_t value)
{
return screenController_.UpdateBrightness(value);//调用ScreenController::UpdateBrightness
}
bool ScreenController::UpdateBrightness(int32_t value)
{
std::lock_guard lock(mutex_);
brightness_ = value;
action_.SetBrightness(value);//调用ScreenAction::SetBrightness
DISPLAY_HILOGI(MODULE_SERVICE, "Update brightness to %{public}d", value);
return true;
}
bool ScreenAction::SetBrightness(int32_t value)
{
if (!hdiFuncs_) {
DISPLAY_HILOGE(MODULE_SERVICE, "Invalid device functions");
return false;
}
//GetValidBrightness检查输入参数是否在[6,255],超出范围取边界值
//SetDisplayBacklight在编号为0的设备设置背光级别
//在ScreenAction::Init()初始化时从driver接口查出的SetDisplayBacklight接口函数(目前看的代码并不支持该背光的特性)
return hdiFuncs_->SetDisplayBacklight(0, GetValidBrightness(value)) == DISPLAY_SUCCESS;
}
4 电源管理服务组件
电源管理服务组件提供如下功能:
- 重启系统。
- 管理休眠运行锁。
- 系统电源状态查询。
4.1 代码目录
/base/powermgr/power_manager
├── interfaces # 接口层
│ ├── innerkits # 内部接口
│ └── kits # 外部接口
├── sa_profile # SA配置文件
└── services # 服务层
│ ├── native # native层
│ └── zidl # zidl层
└── utils # 工具和通用层
4.2 系统电源管理接口
接口使用所需权限:
- 关机权限:
ohos.permission.SHUTDOWN
- 重启权限:
ohos.permission.REBOOT
- 重启并进入recovery模式的权限:
ohos.permission.REBOOT_RECOVERY
系统关机:power.shutdownDevice
function shutdownDevice(reason: string): void;
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
reason | string | 是 | 关机原因。 |
重启设备:power.rebootDevice
function rebootDevice(reason: string): void;
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
reason | string | 是 | 重启原因。 |
检测当前设备的亮灭屏状态之一:
function isScreenOn(callback: AsyncCallback<boolean>): void;
参数:
类型 | 类型 | 必填 | 说明 |
---|---|---|---|
callback | AsyncCallback<boolean> | 是 | 指定的callback回调方法,用于获取返回值。callback返回值:亮屏返回true,灭屏返回false。 |
检测当前设备的亮灭屏状态之二:
function isScreenOn(): Promise<boolean>;
返回值:
类型 | 说明 |
---|---|
Promise<boolean> | Promise实例,用于异步获取返回值,亮屏返回true,灭屏返回false。 |
4.3 Runninglock锁接口
接口使用所需权限:ohos.permission.RUNNING_LOCK
RunningLock锁的类型:
名称 | 默认值 | 描述 |
---|---|---|
BACKGROUND | 1 | 阻止系统休眠的锁。 |
PROXIMITY_SCREEN_CONTROL | 2 | 通过接近或者远离状态来控制亮灭屏的锁。 |
查询系统是否支持该类型的锁之一:
function isRunningLockTypeSupported(type: RunningLockType, callback: AsyncCallback<boolean>): void;
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
type | RunningLockType | 是 | 需要查询的锁的类型。 |
callback | AsyncCallback<boolean> | 是 | 指定的callback回调方法,用于获取返回值。callback返回值:支持返回true,不支持返回false。 |
查询系统是否支持该类型的锁之二:
function isRunningLockTypeSupported(type: RunningLockType): Promise<boolean>;
-
参数:
参数名 类型 必填 说明 type RunningLockType 是 需要查询的锁的类型。 -
返回值:
类型 说明 Promise<boolean> Promise实例,用于异步获取返回值,支持返回true,不支持返回false。
创建RunningLock锁之一:
function createRunningLock(name: string, type: RunningLockType, callback: AsyncCallback<RunningLock>): void;
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
name | string | 是 | 锁的名字。 |
type | RunningLockType | 是 | 要创建的锁的类型。 |
callback | AsyncCallback<RunningLock> | 是 | 指定的callback回调方法,用于获取返回的RunningLock锁对象。 |
创建Runninglock锁之二:
function createRunningLock(name: string, type: RunningLockType): Promise<RunningLock>;
-
参数:
参数名 类型 必填 说明 name string 是 锁的名字。 type RunningLockType 是 要创建的锁的类型。 -
返回值:
类型 说明 Promise<RunningLock> Promise实例,用于异步获取返回的RunningLock锁对象。
锁定和持有RunningLock:
function lock(timeout: number): void;
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
timeout | number | 否 | 锁定和持有RunningLock的时长。 |
释放Runninglock锁:
function unlock(): void;
查询当前Runninglock是持有状态,还是释放状态:
function isUsed(): boolean;
返回值:
类型 | 说明 |
---|---|
boolean | 当前RunningLock是持有状态返回true,释放状态返回false。 |
4.4 Power Manager Service服务启动
Power Manager Service服务被打包到foundation进程,启动过程基本同电池服务(Battery Service)的启动,详细启动流程可以看System Ability管理相关的资料。
注册信息:
<systemability>
<name>3301</name>
<libpath>libpowermgrservice.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
注册代码:
//构建入参为serviceid、runoncreate
PowerMgrService::PowerMgrService() : SystemAbility(POWER_MANAGER_SERVICE_ID, true) {}
auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
//调用SystemAbility接口注册BatteryService实例
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(pms.GetRefPtr());
System Ability管理模块调用PowerMgrService的启动函数实现电源管理服务组件的启动:
void PowerMgrService::OnStart()
{
POWER_HILOGI(MODULE_SERVICE, "OnStart enter.");
if (ready_) {
POWER_HILOGE(MODULE_SERVICE, "OnStart is ready, nothing to do.");
return;
}
if (!Init()) {
POWER_HILOGE(MODULE_SERVICE, "OnStart call init fail");
return;
}
//PowerMgrService服务发布到System Ability管理模块
if (!Publish(DelayedSpSingleton<PowerMgrService>::GetInstance())) {
POWER_HILOGE(MODULE_SERVICE, "OnStart register to system ability manager failed.");
return;
}
ready_ = true;//设置已启动
POWER_HILOGI(MODULE_SERVICE, "OnStart and add system ability success.");
}
//因为初始化做的事情确实很多,下面展开分析
bool PowerMgrService::Init()
{
POWER_HILOGI(MODULE_SERVICE, "Init start");
if (!eventRunner_) {
eventRunner_ = AppExecFwk::EventRunner::Create(POWERMGR_SERVICE_NAME);
if (eventRunner_ == nullptr) {
POWER_HILOGE(MODULE_SERVICE, "Init failed due to create EventRunner");
return false;
}
}
//创建PowermsEventHandler实例
if (!handler_) {
handler_ = std::make_shared<PowermsEventHandler>(eventRunner_, pms);
}
//创建RunningLockMgr实例
if (!runningLockMgr_) {
runningLockMgr_ = std::make_shared<RunningLockMgr>(pms);
}
//执行RunningLockMgr的Init初始化,并创建RunningLockAction实例
if (!runningLockMgr_->Init()) {
POWER_HILOGE(MODULE_SERVICE, "OnStart init fail");
return false;
}
//创建PowerStateMachine实例,执行PowerStateMachine的Init初始化,并创建DeviceStateAction实例
if (!PowerStateMachineInit()) {
POWER_HILOGE(MODULE_SERVICE, "power state machine init fail!");
}
POWER_HILOGI(MODULE_SERVICE, "Init success");
return true;
}
bool PowerStateMachine::Init()
{
POWER_HILOGI(MODULE_SERVICE, "PowerStateMachine:: Init start");
stateAction_ = PowerMgrFactory::GetDeviceStateAction();
if (powerStateCBDeathRecipient_ == nullptr) {
powerStateCBDeathRecipient_ = new PowerStateCallbackDeathRecipient();
}
if (!powerMgrMonitor_.Start()) {
POWER_HILOGE(MODULE_SERVICE, "Failed to start monitor");
return false;
}
POWER_HILOGI(MODULE_SERVICE, "PowerStateMachine:: Init success!");
return true;
}
//此函数是在powerMgrMonitor_.Start()中调用
bool PowerMgrMonitor::RegisterSubscriber(const sptr<CesInfo>& info)
{
static const int32_t MAX_RETRY_TIMES = 2;
auto succeed = false;
//EVENT_HANDLES只注册了一个接口HandleStartUpCompleted
shared_ptr<Ces> s = make_shared<EventSubscriber>(info, eventHandles_);
// Retry to register subscriber due to timming issues between system abilities
for (int32_t tryTimes = 0; tryTimes < MAX_RETRY_TIMES; tryTimes++) {
//注册到通用事件管理模块,订阅EVENT_HANDLES中注册的消息
succeed = CommonEventManager::SubscribeCommonEvent(s);
if (succeed) {
break;
}
POWER_HILOGE(MODULE_SERVICE, "Sleep for a while and retry to register subscriber");
usleep(50000); // sleep 50ms
}
if (!succeed) {
POWER_HILOGE(MODULE_SERVICE, "Failed to register subscriber");
return false;
}
subscriber_ = s;
POWER_HILOGI(MODULE_SERVICE, "Succeed to register subscriber");
return true;
}
4.5 系统电源管理接口调用流程
以shutdown为例解析接口调用流程,其它接口除了功能差异,流程都差不多。
代码:
import power from '@ohos.power';
power.shutdownDevice("shutdown_test");
static napi_value ShutdownDevice(napi_env env, napi_callback_info info)
{
//1.读取并检查入参,判断是否为shutdown操作
//2.调用g_powerMgrClient.ShutDownDevice(std::string(reason));
return RebootOrShutdown(env, info, false);
}
void PowerMgrClient::ShutDownDevice(const std::string& reason)
{
//查找POWER_MANAGER_SERVICE_ID,即上面注册的PowerMgrService服务
//这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxServiceStub-->xxService。
RETURN_IF(Connect() != ERR_OK);
POWER_HILOGE(MODULE_INNERKIT, "%{public}s called.", __func__);
//执行PowerMgrService::ShutDownDevice(const std::string& reason)
proxy_->ShutDownDevice(reason);
}
void PowerMgrService::ShutDownDevice(const std::string& reason)
{
pid_t pid = IPCSkeleton::GetCallingPid();
auto uid = IPCSkeleton::GetCallingUid();
//判断执行权限
if ((uid >= APP_FIRST_UID) && !Permission::CheckCallingPermission("ohos.permission.REBOOT")) {
POWER_HILOGE(MODULE_SERVICE, "%{public}s Request failed, %{public}d permission check fail", __func__, pid);
return;
}
POWER_HILOGI(MODULE_SERVICE, "PID: %{public}d Call %{public}s !", pid, __func__);
shutdownService_.Shutdown(reason);
}
void ShutdownService::Shutdown(const std::string& reason)
{
RebootOrShutdown(reason, false);
}
void ShutdownService::RebootOrShutdown(const std::string& reason, bool isReboot)
{
if (started_) {
POWER_HILOGE(MODULE_SERVICE, "Shutdown is already running.");
return;
}
started_ = true;
make_unique<thread>([=] {
Prepare();//发送COMMON_EVENT_SHUTDOWN公共事件
POWER_HILOGD(MODULE_SERVICE, "reason = %{public}s, reboot = %{public}d", reason.c_str(), isReboot);
if (devicePowerAction_ != nullptr) {
//执行DevicePowerAction::Shutdown(const std::string& reason)
isReboot ? devicePowerAction_->Reboot(reason) : devicePowerAction_->Shutdown(reason);
}
started_ = false;
})->detach();
}
void DevicePowerAction::Shutdown(const std::string& reason)
{
POWER_HILOGI(MODULE_SERVICE, "Shutdown executing.");
//执行系统调用,进行shutdown操作
syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF, reason.c_str());
}
4.6 系统休眠锁接口调用流程
在PowerMgrService服务启动初始化节点创建了RunningLockMgr的管理实例,接口调用流程和电源管理接口基本上差不多,此处不在罗列,实现系统休眠锁的核心原理如下:
- 加锁的
sysfs
文件:/sys/power/wake_lock
,用户程序向文件写入一个字符串,即可创建一个wakelock
,该字符串就是wakelock
的名字。该wakelock
可以阻止系统进入低功耗模式。 - 解锁的
sysfs
文件:/sys/power/wake_unlock
,用户程序向文件写入相同的字符串,即可注销一个wakelock
。 - 当系统中所有的wakelock都注销后,系统可以自动进入低功耗状态。
4.7 手机近光传感器触发的亮灭屏流程
近光传感器的流程本文不涉及,只从调用PowerMgrClient接口开始,代码如下:
void ProximitySensor::StartUp(PowerMgr::WakeupDeviceType operationType, std::string wakeupReason)
{
PowerMgr::PowerMgrClient::GetInstance().WakeupDevice(operationType, wakeupReason);
}
void PowerMgrClient::WakeupDevice(WakeupDeviceType reason, const std::string& details)
{
//查找POWER_MANAGER_SERVICE_ID,即上面注册的PowerMgrService服务
//这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxServiceStub-->xxService。
RETURN_IF(Connect() != ERR_OK);
// Param details's length must > 0
if (details.empty()) {
POWER_HILOGE(MODULE_INNERKIT, "%{public}s : detail length is 0, Wakeup failed!", __func__);
return;
}
std::string subDetails;
if (details.length() > MAX_STRING_LENGTH) {
POWER_HILOGI(MODULE_INNERKIT, "%{public}s : detail = %{public}s, length is larger than %{public}d, \
do substring!", __func__, details.c_str(), MAX_STRING_LENGTH);
subDetails = details.substr(0, MAX_STRING_LENGTH);
} else {
subDetails = details;
}
//调用PowerMgrService的WakeupDevice接口
proxy_->WakeupDevice(GetTickCount(), reason, subDetails);
POWER_HILOGI(MODULE_INNERKIT, " Calling WakeupDevice success.");
}
void PowerMgrService::WakeupDevice(int64_t callTimeMs, WakeupDeviceType reason, const std::string& details)
{
auto uid = IPCSkeleton::GetCallingUid();
if (uid >= APP_FIRST_UID) {
POWER_HILOGE(MODULE_SERVICE, "%{public}s Request failed, illegal calling uid %{public}d.", __func__, uid);
return;
}
pid_t pid = IPCSkeleton::GetCallingPid();
powerStateMachine_->WakeupDeviceInner(pid, callTimeMs, reason, details, "OHOS");
}
void PowerStateMachine::WakeupDeviceInner(pid_t pid, int64_t callTimeMs, WakeupDeviceType type,
const std::string& details, const std::string& pkgName)
{
POWER_HILOGI(MODULE_SERVICE, "PID: %{public}d Try to Wakeup Device!!", pid);
// Check the screen state
if (stateAction_ != nullptr) {//PowerStateMachine初始化时创建的DeviceStateAction实例
stateAction_->Wakeup(callTimeMs, type, details, pkgName);
}
mDeviceState_.lastWakeupDeviceTime = callTimeMs;
POWER_HILOGD(MODULE_SERVICE, "Wakeup Device Call Binder Success!!");
}
void DeviceStateAction::Wakeup(int64_t callTimeMs, WakeupDeviceType type, const string& details,
const string& pkgName)
{
SystemSuspendController::GetInstance().DisableSuspend();
//调用DisplayManager的亮屏操作
DisplayManager::SetScreenState(ScreenState::SCREEN_STATE_ON);
}
4.8 发布公共事件的流程
电源管理服务只是实现了公共事件的部分流程,并未完全实现消息的发布,代码如下:
void OnReceiveEvent(const EventFwk::CommonEventData &data) override
{
HandleEvent(data.GetWant());
}
void PowerMgrMonitor::EventSubscriber::HandleEvent(const IntentWant& want)
{
auto action = want.GetAction();
auto it = eventHandles_.find(action);
if (it == eventHandles_.end()) {
POWER_HILOGI(MODULE_SERVICE, "Ignore event: %{public}s", action.c_str());
return;
}
POWER_HILOGI(MODULE_SERVICE, "Handle event: %{public}s", action.c_str());
it->second(want);
}
void PowerMgrMonitor::HandleScreenStateChanged(const IntentWant& want) const
{
bool isScreenOn = want.GetAction() == CommonEventSupport::COMMON_EVENT_SCREEN_ON;
POWER_HILOGD(MODULE_SERVICE, "Screen is %{public}s", isScreenOn ? "on" : "off");
DelayedSpSingleton<PowerMgrService>::GetInstance()->GetPowerStateMachine()->ReceiveScreenEvent(isScreenOn);
}
void PowerStateMachine::ReceiveScreenEvent(bool isScreenOn)
{
std::lock_guard lock(mutex_);
auto prestate = mDeviceState_.screenState.state;
mDeviceState_.screenState.lastUpdateTime = GetTickCount();
mDeviceState_.screenState.state = isScreenOn ? ScreenStateType::SCREEN_ON : ScreenStateType::SCREEN_OFF;
if (prestate != mDeviceState_.screenState.state) {
NotifyPowerStateChanged(isScreenOn ? PowerState::AWAKE : PowerState::INACTIVE);
}
POWER_HILOGI(MODULE_SERVICE, "receive new screen event, new state is %{public}d, at %{public}" PRId64 "",
mDeviceState_.screenState.state, mDeviceState_.screenState.lastUpdateTime);
}
void PowerStateMachine::NotifyPowerStateChanged(PowerState state)
{
POWER_HILOGI(MODULE_SERVICE, "%{public}s state = %u, listeners.size = %d", __func__,
static_cast<uint32_t>(state), static_cast<unsigned int>(powerStateListeners_.size()));
int64_t now = GetTickCount();
// Send Notification event
SendEventToPowerMgrNotify(state, now);
//执行注册的回调函数,目前没有发布注册接口
for (auto& listener : powerStateListeners_) {
listener->OnPowerStateChanged(state);
}
}
void PowerStateMachine::SendEventToPowerMgrNotify(PowerState state, int64_t callTime)
{
auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
if (pms == nullptr) {
POWER_HILOGE(MODULE_SERVICE, "SendEventToPowerMgrNotify pms is Null, Fail!!");
return;
}
auto notify = pms->GetPowerMgrNotify();
if (notify == nullptr) {
POWER_HILOGE(MODULE_SERVICE, "SendEventToPowerMgrNotify notify is Null, Fail!!");
return;
}
if (state == PowerState::AWAKE) {
notify->PublishScreenOnEvents(callTime);
} else {
notify->PublishScreenOffEvents(callTime);
}
}
void PowerMgrNotify::PublishScreenOnEvents(int64_t eventTime)
{
PublishEvents(eventTime, screenOnWant_);
}
//发送COMMON_EVENT_SCREEN_ON公共事件
void PowerMgrNotify::PublishEvents(int64_t eventTime, sptr<IntentWant> want)
{
if ((want == nullptr) || (publishInfo_ == nullptr)) {
POWER_HILOGE(MODULE_SERVICE, "Invalid parameter");
return;
}
POWER_HILOGI(MODULE_SERVICE, "Start to publish event %{public}s at %{public}lld",
want->GetAction().c_str(), static_cast<long long>(eventTime));
CommonEventData event(*want);
CommonEventManager::PublishCommonEvent(event, *publishInfo_, nullptr);
POWER_HILOGI(MODULE_SERVICE, "Publish event %{public}s done", want->GetAction().c_str());
}
//但是目前系统只注册了COMMON_EVENT_BOOT_COMPLETED这一个事件的处理函数,screen on/off事件没注册
//而HandleStartUpCompleted也没有具体实现消息的发布,只是输出一条日志。
const map<string, PowerMgrMonitor::HandleEventFunc> PowerMgrMonitor::EVENT_HANDLES {
{CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED, &PowerMgrMonitor::HandleStartUpCompleted},
};
5 总结
本文主要和大家分享了OpenHarmony电源管理子系统的实现,重点分析了电池服务组件、显示控制组件和电源管理服务组件的服务注册、启动,以及典型的接口调用流程,做了较为详细的代码说明,希望通过本文您能初步掌握电源管理子系统的关键功能和核心流程。关于OpenHarmony其它子系统的分析,请关注后续文章。
更多原创内容请关注:开鸿 HarmonyOS 学院
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
看到这么详细的文章,感觉老师的新书要来了
开鸿运当头,启蒙生万象