OpenHarmony开发者论坛

标题: OpenHarmony4.0源码解析之电源管理子系统 [打印本页]

作者: 深开鸿_王奎    时间: 2023-10-20 15:08
标题: OpenHarmony4.0源码解析之电源管理子系统
[md]OpenHarmony源码解析之电源管理子系统

作者:深开鸿-王奎

## 简介

电源管理子系统是OpenHarmony的基本能力子系统,有电池服务组件、显示控制组件和电源管理服务组件,主要提供如下功能:

1. 重启服务:系统重启和下电。
2. 系统电源管理服务:系统电源状态管理和休眠运行锁管理。
3. 显示相关的能耗调节:包括根据环境光调节背光亮度,和根据接近光亮灭屏。
4. 省电模式 :在不损害主要功能和性能的前提下,提供一种低功耗操作模式 。
5. 电池服务:支持充放电、电池和充电状态的监测,包括状态的更新和上报,还包括关机充电。
6. 温控 :在设备温度到一定程度之后对应用、SoC、外设进行管控,限制温升 。
7. 耗电统计: 主要包括软件耗电和硬件耗电统计,以及单个应用的耗电统计 。
8. 轻设备电池服务。
9. 轻设备电源管理服务。

开发者通过电源管理子系统提供的接口,可以根据场景使用:

- Power Manager提供的接口,可以进行申请和释放休眠运行锁RunningLock、设置电源模式、重启设备、关机等操作,同时也可以通过公共事件来监听省电模式和关机状态的变化。
- Battery Manager提供了电池信息查询的接口,同时开发者也可以通过公共事件监听电池状态和充放电状态的变化。
- Thermal Manager提供的设备温升状态的查询接口,同时开发者也可以通过注册回调和公共事件来监听设备温升状态。
- Battery Statistics 提供了软硬件耗电统计的功能,可以查询硬件耗电或者应用耗电情况。
- Display Power Manager 提供了亮度设置接口。

本文重点分析电池服务组件、显示控制组件和电源管理服务组件发布的接口和关键流程代码。文中涉及到HDF驱动框架、SystemAbility框架等内容只是简单提及,不做详细分析。

OpenHarmony架构图
![OpenHarmony.png](data/attachment/forum/202310/20/145543dn6euyo6cckcuaxd.png "OpenHarmony.png")

电源管理子系统架构图
![PowerMgrArch.png](data/attachment/forum/202310/20/145606baz6s4xaxttabsxh.png "owerMgrArch.png")

## 电池服务组件

电池服务组件提供如下功能:

1. 电池信息查询。
2. 充放电状态查询。
3. 关机充电。

### 电池和充电属性接口

该模块主要提供电池状态和充放电状态的查询接口。

batteryInfo,描述电池信息。

| 名称                           | 类型                 | 可读 | 可写 | 说明                                                       |
| ------------------------------ | -------------------- | ---- | ---- | ---------------------------------------------------------- |
| batterySOC                     | number               | 是   | 否   | 表示当前设备剩余电池电量百分比。                           |
| chargingStatus                 | BatteryChargeState   | 是   | 否   | 表示当前设备电池的充电状态。                               |
| healthStatus                   | BatteryHealthState   | 是   | 否   | 表示当前设备电池的健康状态。                               |
| pluggedType                    | BatteryPluggedType   | 是   | 否   | 表示当前设备连接的充电器类型。                             |
| voltage                        | number               | 是   | 否   | 表示当前设备电池的电压,单位微伏。                         |
| technology                     | string               | 是   | 否   | 表示当前设备电池的技术型号。                               |
| batteryTemperature             | number               | 是   | 否   | 表示当前设备电池的温度,单位0.1摄氏度。                    |
| isBatteryPresent7+             | boolean              | 是   | 否   | 表示当前设备是否支持电池或者电池是否在位。                 |
| batteryCapacityLevel9+         | BatteryCapacityLevel | 是   | 否   | 表示当前设备电池电量的等级。                               |
| estimatedRemainingChargeTime9+ | number               | 是   | 否   | 表示当前设备充满电的预估时间,单位毫秒。此接口为系统接口。 |
| totalEnergy9+                  | number               | 是   | 否   | 表示当前设备电池的总容量,单位毫安时。此接口为系统接口。   |
| nowCurrent9+                   | number               | 是   | 否   | 表示当前设备电池的电流,单位毫安。此接口为系统接口。       |
| remainingEnergy9+              | 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      | 表示电池健康状态为僵死状态。 |

BatteryCapacityLevel,表示电池电量等级的枚举。

| 名称           | 值   | 说明                         |
| -------------- | ---- | ---------------------------- |
| LEVEL_FULL     | 1    | 表示电池电量等级为满电量。   |
| LEVEL_HIGH     | 2    | 表示电池电量等级为高电量。   |
| LEVEL_NORMAL   | 3    | 表示电池电量等级为正常电量。 |
| LEVEL_LOW      | 4    | 表示电池电量等级为低电量。   |
| LEVEL_WARNING  | 5    | 表示电池电量等级为告警电量。 |
| LEVEL_CRITICAL | 6    | 表示电池电量等级为极低电量。 |
| LEVEL_SHUTDOWN | 7    | 表示电池电量等级为关机电量。 |

CommonEventBatteryChangedKey,表示COMMON_EVENT_BATTERY_CHANGED通用事件附加信息的查询键。

| 名称                 | 值              | 说明                                               |
| -------------------- | --------------- | -------------------------------------------------- |
| EXTRA_SOC            | "soc"           | 表示剩余电池电量百分比的查询键。                   |
| EXTRA_CHARGE_STATE   | "chargeState"   | 表示当前设备电池充电状态的查询键。                 |
| EXTRA_HEALTH_STATE   | "healthState"   | 表示当前设备电池健康状态的查询键。                 |
| EXTRA_PLUGGED_TYPE   | "pluggedType"   | 表示当前设备连接的充电器类型的查询键。             |
| EXTRA_VOLTAGE        | "voltage"       | 表示当前设备电池电压的查询键。                     |
| EXTRA_TECHNOLOGY     | "technology"    | 表示当前设备电池技术型号的查询键。                 |
| EXTRA_TEMPERATURE    | "temperature"   | 表示当前设备电池温度的查询键。                     |
| EXTRA_PRESENT        | "present"       | 表示当前设备是否支持电池或者电池是否在位的查询键。 |
| EXTRA_CAPACITY_LEVEL | "capacityLevel" | 表示当前设备电池电量等级的查询键。                 |

### 代码目录

```
base/powermgr/battery_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                       # 工具和通用层
```

### Battery Service服务启动

Battery Service服务被打包到foundation进程。

System Ability管理模块用于管理系统基础能力,本服务需要向该模块注册,如果没有编写profile配置,则System Ability管理模块在启动时不会注册该服务。详细启动流程可以看System Ability管理相关的资料。

注册信息:

```json
{
    "process": "foundation",
    "systemability": [
        {
            "name": 3302,
            "libpath": "libbatteryservice.z.so",
            "run-on-create": true,
            "distributed": false,
            "dump_level": 1
        }
    ]
}
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Tips:
0.注册信息用json格式取代先前的xml,其他内容不变
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
```

注册代码:

```c++
//调用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的启动函数实现电池服务组件的启动:

```c++
void BatteryService::OnStart()
{
    //如果已启动则返回(BatteryService是单实例服务,只会启动一个)
    if (ready_) {
        BATTERY_HILOGD(COMP_SVC, "Service is ready, nothing to do");
        return;
    }
   
    //创建BatterysrvEventHandler实例
    //等待CommonEventService服务启动完成之后初始化完成
    if (!(Init())) {
        BATTERY_HILOGE(COMP_SVC, "Call init failed");
        return;
    }
   
    //向OHOS::HDI::ServiceManager 注册状态监听
    RegisterHdiStatusListener();
   
    //BatteryService服务发布到System Ability管理模块
    if (!Publish(this)) {
        BATTERY_HILOGE(COMP_SVC, "Register to system ability manager failed");
        return;
    }
   
    // 对指定SA,MISCDEVICE_SERVICE_ABILITY_ID 的监听,当监听的该SA已被publish到SAmgr后,就会触发OnAddSystemAbility
    AddSystemAbilityListener(MISCDEVICE_SERVICE_ABILITY_ID);
    ready_ = true;
}
```

### BatteryInterfaceDriver启动

BatteryInterfaceDriver是HDI(即驱动接口)层服务,打包在power_host进程。本文的代码分析不包括驱动程序框架的完整驱动加载过程,主要分析batteryd的实现。

驱动程序 (Driver Entry)入口中的三个主要接口:

1. Bind 接口:实现驱动接口实例化绑定,如果需要发布驱动接口,会在驱动加载过程中被调用,实例化该接口的驱动服务并和 DeviceObject 绑定。
2. Init 接口:实现驱动的初始化,返回错误将中止驱动加载流程。
3. Release 接口:实现驱动的卸载,在该接口中释放驱动实例的软硬件资源。

实现batteryd驱动程序初始化接口:

```c++
static struct HdfDriverEntry g_batteryInterfaceDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "battery_interface_service",
    .Bind = HdfBatteryInterfaceDriverBind,
    .Init = HdfBatteryInterfaceDriverInit,
    .Release = HdfBatteryInterfaceDriverRelease,
};

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
//宏声明导出驱动程序入口,驱动框架启动时查找到moduleName = "batteryd",则按照入口信息启动batteryd的服务。   
HDF_INIT(g_batteryInterfaceDriverEntry);
#ifdef __cplusplus
}
#endif /* __cplusplus */

static int32_t HdfBatteryInterfaceDriverInit([[maybe_unused]] struct HdfDeviceObject *deviceObject)
{
    return HDF_SUCCESS;
}

static int32_t HdfBatteryInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
{
    auto *hdfBatteryInterfaceHost = new (std::nothrow) HdfBatteryInterfaceHost;
    if (hdfBatteryInterfaceHost == nullptr) {
        BATTERY_HILOGE(COMP_HDI, "%{public}s: failed to create HdfBatteryInterfaceHost object", __func__);
        return HDF_FAILURE;
    }
    //此处绑定了BatteryInterfaceDriverDispatch作为消息处理函数。
    hdfBatteryInterfaceHost->ioService.Dispatch = BatteryInterfaceDriverDispatch;
    hdfBatteryInterfaceHost->ioService.Open = nullptr;
    hdfBatteryInterfaceHost->ioService.Release = nullptr;

    auto serviceImpl = IBatteryInterface::Get(true);
    if (serviceImpl == nullptr) {
        BATTERY_HILOGE(COMP_HDI, "%{public}s: failed to get of implement service", __func__);
        delete hdfBatteryInterfaceHost;
        return HDF_FAILURE;
    }

    hdfBatteryInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
        IBatteryInterface::GetDescriptor());
    if (hdfBatteryInterfaceHost->stub == nullptr) {
        BATTERY_HILOGE(COMP_HDI, "%{public}s: failed to get stub object", __func__);
        delete hdfBatteryInterfaceHost;
        return HDF_FAILURE;
    }
    //IO Service 完成 IPC 通信的客户端消息请求封装,IO Dispatcher 完成驱动服务端消息请求封装
    //客户端消息通过 IPC 通信到达服务端并分发给 IO Dispatcher 处理。
    deviceObject->service = &hdfBatteryInterfaceHost->ioService;
    return HDF_SUCCESS;
}

//Release HdfBatteryInterfaceDriver
static void HdfBatteryInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
{
    if (deviceObject->service == nullptr) {
        BATTERY_HILOGE(COMP_HDI, "HdfBatteryInterfaceDriverRelease not initted");
        return;
    }

    auto *hdfBatteryInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfBatteryInterfaceHost, ioService);
    delete hdfBatteryInterfaceHost;
}
```

实现驱动程序初始化后,需要将驱动程序入口通过驱动声明宏导出,这样驱动框架才能在启动时识别到驱动程序的存在,驱动才能被加载:

```c++
#define HDF_INIT(module)  HDF_DRIVER_INIT(module)
```

这里将 HDF_INIT 宏展开:

```c++
#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))
```

### 电池batteryInfo信息查询流程

以获取当前设备剩余电池容量(batterySOC)为例,下面为完整处理流程:

流程图:
![getbatteryInfo.png](data/attachment/forum/202310/20/150325o9y7yy97c9crvt7i.png "getbatteryInfo.png")

代码:

```c++
//导入模块
import batteryInfo from '@ohos.batteryInfo';
//调用batterySOC查询接口
var batterySoc = batteryInfo.batterySOC;


thread_local static BatterySrvClient& g_battClient = BatterySrvClient::GetInstance();

//注册在动态库中的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));

    BATTERY_HILOGD(FEATURE_BATT_INFO, "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-->xxStub-->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()
{
    // 是否mock
    if (isMockCapacity_) {
        BATTERY_HILOGD(FEATURE_BATT_INFO, "Return mock battery capacity");
        return batteryInfo_.GetCapacity();
    }
    std::shared_lock<std::shared_mutex> lock(mutex_);
    if (iBatteryInterface_ == nullptr) {
        BATTERY_HILOGE(FEATURE_BATT_INFO, "iBatteryInterface_ is nullptr");
        return ERR_NO_INIT;
    }
    int32_t capacity = BATTERY_FULL_CAPACITY;
    //调用 BatteryInterface::GetCapacity(capacity)
    iBatteryInterface_->GetCapacity(capacity);
    return capacity;
}

// BatteryInterfaceImpl 实现IBatteryInterface的纯虚函数
int32_t BatteryInterfaceImpl::GetCapacity(int32_t& capacity)
{
    // 调用 PowerSupplyProvider:arseCapacity(...)
    return provider_->arseCapacity(&capacity);
}

int32_t PowerSupplyProvider:arseCapacity(int32_t* capacity) const
{
    char buf[MAX_BUFF_SIZE] = {0};
   
    // 从capacity的系统文件读取当前设备剩余电池容量中至buf
    int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.capacityPath.c_str(), buf, sizeof(buf));
    if (ret != HDF_SUCCESS) {
        return ret;
    }
   
    // 转换为十进制
    int32_t value = ParseInt(buf);
    *capacity = value;

    return HDF_SUCCESS;
}


int32_t PowerSupplyProvider::ReadBatterySysfsToBuff(const char* path, char* buf, size_t size) const
{  
    // ReadSysfsFile
    int32_t ret = ReadSysfsFile(path, buf, size);
    if (ret != HDF_SUCCESS) {
        BATTERY_HILOGW(FEATURE_BATT_INFO, "read path failed, ret: %{public}d", ret);
        return ret;
    }

    return HDF_SUCCESS;
}

int32_t PowerSupplyProvider::ReadSysfsFile(const char* path, char* buf, size_t size) const
{
    int32_t fd = open(path, O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
    if (fd < NUM_ZERO) {
        BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to open file");
        return HDF_ERR_IO;
    }

    size_t readSize = read(fd, buf, size - 1);
    buf[readSize] = '\0';
    Trim(buf);
    close(fd);

    return HDF_SUCCESS;
}
```

### 电池batteryinfo信息变更发布流程

```c++
//在BatteryInterfaceImpl::Init() 启动初始化阶段启动了本线程,用于处理kernel发来的消息,部分代码如下:
void BatteryThread::StartThread(void* service)
{
    Init(service);
    Run(service);
}
void BatteryThread::Run(void* service)
{
    std::thread batteryThread(&BatteryThread:oopingThreadEntry, this, service);
    pthread_setname_np(batteryThread.native_handle(), "battery_thread");
    batteryThread.detach();
}
int32_t BatteryThread:oopingThreadEntry(void* arg)
{
    int32_t nevents = 0;
    size_t size = callbacks_.size();
    struct epoll_event events[size];

    while (true) {
        if (!nevents) {
            CycleMatters();
        }

        HandleStates();

        int32_t timeout = epollInterval_;
        int32_t waitTimeout = UpdateWaitInterval();
        if ((timeout < 0) || (waitTimeout > 0 && waitTimeout < timeout)) {
            timeout = waitTimeout;
        }
        // 等待监听的所有的fd相应的事件的产生
        nevents = epoll_wait(epFd_, events, static_cast<int32_t>(size), timeout);
        if (nevents <= 0) {
            continue;
        }

        // 在callbacks_中,根据ueventFd_, 调用void BatteryThread::UeventCallback(void* service)
        for (int32_t n = 0; n < nevents; ++n) {
            if (events[n].data.ptr) {
                auto* func = const_cast<BatteryThread*>(this);
                (callbacks_.find(events[n].data.fd)->second)(func, arg);
            }
        }
    }
}

void BatteryThread::UeventCallback(void* service)
{
    char msg[UEVENT_MSG_LEN + UEVENT_RESERVED_SIZE] = { 0 };
   
    ssize_t len = recv(ueventFd_, msg, UEVENT_MSG_LEN, 0);
    if (len < 0 || len >= UEVENT_MSG_LEN) {
        BATTERY_HILOGI(COMP_HDI, "recv return msg is invalid, len: %{public}zd", len);
        return;
    }

    // msg separator
    msg[len] = '\0';
    msg[len + 1] = '\0';
    if (!IsPowerSupplyEvent(msg)) {
        return;
    }
    UpdateBatteryInfo(service);
}

void BatteryThread::UpdateBatteryInfo(void* service)
{
    BatteryInfo event = {};
    std::unique_ptr<BatterydInfo> batteryInfo = std::make_unique<BatterydInfo>();
    if (batteryInfo == nullptr) {
        BATTERY_HILOGE(FEATURE_BATT_INFO, "make_unique BatterydInfo error");
        return;
    }
    // 从系统文件中读取信息到batteryInfo
    provider_->UpdateInfoByReadSysFile(batteryInfo.get());
   
    //将batteryInfo 赋值event
    event.capacity = batteryInfo->capacity_;
    event.voltage= batteryInfo->voltage_;
    event.temperature = batteryInfo->temperature_;
    event.healthState = batteryInfo->healthState_;
    event.pluggedType = batteryInfo->pluggedType_;
    event.pluggedMaxCurrent = batteryInfo->pluggedMaxCurrent_;
    event.pluggedMaxVoltage = batteryInfo->pluggedMaxVoltage_;
    event.chargeState = batteryInfo->chargeState_;
    event.chargeCounter = batteryInfo->chargeCounter_;
    event.present = batteryInfo->present_;
    event.technology = batteryInfo->technology_;
    event.curNow = batteryInfo->curNow_;
    event.remainEnergy = batteryInfo->remainEnergy_;
    event.totalEnergy = batteryInfo->totalEnergy_;

    if (g_callback != nullptr) {
        
        // 向注册的 Callback or Subscriber发送电池状态变更消息
        g_callback->Update(event);
    } else {
        BATTERY_HILOGI(FEATURE_BATT_INFO, "g_callback is nullptr");
    }
}

// 读取系统文件中的对应的数据至info
void PowerSupplyProvider::UpdateInfoByReadSysFile(struct BatterydInfo* info) const
{
    ParseCapacity(&info->capacity_);
    ParseVoltage(&info->voltage_);
    ParseTemperature(&info->temperature_);
    ParseHealthState(&info->healthState_);
    ParseChargeState(&info->chargeState_);
    ParseChargeCounter(&info->chargeCounter_);
    ParseCurrentNow(&info->curNow_);
    ParseCurrentAverage(&info->curAverage_);
    ParseRemainEnergy(&info->remainEnergy_);
    ParseTotalEnergy(&info->totalEnergy_);
    ParsePresent(&info->present_);

    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_);

    info->technology_ = INVALID_STRING_VALUE;
    ParseTechnology(info->technology_);
    // 将数据保存在 g_batteryInfo
    CopyBatteryInfo(info);
}

void PowerSupplyProvider::CopyBatteryInfo(const struct BatterydInfo* info) const
{
    g_batteryInfo.capacity_ = info->capacity_;
    g_batteryInfo.voltage_ = info->voltage_;
    g_batteryInfo.temperature_ = info->temperature_;
    g_batteryInfo.healthState_ = info->healthState_;
    g_batteryInfo.pluggedType_ = info->pluggedType_;
    g_batteryInfo.pluggedMaxCurrent_ = info->pluggedMaxCurrent_;
    g_batteryInfo.pluggedMaxVoltage_ = info->pluggedMaxVoltage_;
    g_batteryInfo.chargeState_ = info->chargeState_;
    g_batteryInfo.chargeCounter_ = info->chargeCounter_;
    g_batteryInfo.curNow_ = info->curNow_;
    g_batteryInfo.curAverage_ = info->curAverage_;
    g_batteryInfo.totalEnergy_ = info->totalEnergy_;
    g_batteryInfo.remainEnergy_ = info->remainEnergy_;
    g_batteryInfo.present_ = info->present_;
    g_batteryInfo.technology_ = info->technology_;
}
// framework service端
bool BatteryService::RegisterBatteryHdiCallback()
{
    std::lock_guard<std::shared_mutex> lock(mutex_);
    if (iBatteryInterface_ == nullptr) {
        iBatteryInterface_ = V1_2::IBatteryInterface::Get();
        BATTERY_HILOGE(COMP_SVC, "failed to get battery hdi interface");
        RETURN_IF_WITH_RET(iBatteryInterface_ == nullptr, false);
    }
   
    // 向BatteryInterface 注册一个 BatteryCallback,
    sptr<V1_2::IBatteryCallback> callback = new BatteryCallback();
    ErrCode ret = iBatteryInterface_->Register(callback);
    if (ret < 0) {
        BATTERY_HILOGE(COMP_SVC, "register callback failed");
        return false;
    }
   
    // 调用 BatteryCallback::RegisterBatteryEvent 更新回调处理函数(static)为HandleBatteryCallbackEvent
    BatteryCallback::BatteryEventCallback eventCb =
        std::bind(&BatteryService::HandleBatteryCallbackEvent, this, std::placeholders::_1);
    BatteryCallback::RegisterBatteryEvent(eventCb);
    return true;
}
----------------------------------------------------------------------------------------------------------
// --补充部分 begin   
// BatteryCallback 实现IBatteryCallback的update,
// BatteryThread::UpdateBatteryInfo中调用update时,将会调用service的注册的回调处理函数HandleBatteryCallbackEvent
int32_t BatteryCallback::Update(const HDI::Battery::V1_2::BatteryInfo& event)
{
    if (eventCb_ == nullptr) {
        BATTERY_HILOGW(FEATURE_BATT_INFO, "eventCb_ is nullptr, cannot update battery info");
        return HDF_FAILURE;
    }
    return eventCb_(event);
}

// 更新static变量所指向的回调函数
int32_t BatteryCallback::RegisterBatteryEvent(const BatteryEventCallback& eventCb)
{
    eventCb_ = eventCb;
    return HDF_SUCCESS;
}
// --补充部分 end
---------------------------------------------------------------------------------------------------------

int32_t BatteryService::HandleBatteryCallbackEvent(const V1_2::BatteryInfo& event)
{
    if (isMockUnplugged_ || isMockCapacity_) {
        return ERR_OK;
    }

    ConvertingEvent(event);
    RETURN_IF_WITH_RET(lastBatteryInfo_ == batteryInfo_, ERR_OK);
    HandleBatteryInfo();
    return ERR_OK;
}

//根据event事件,更新batteryInfo_
void BatteryService::ConvertingEvent(const V1_2::BatteryInfo& event)
{
    if (!isMockCapacity_) {
        batteryInfo_.SetCapacity(event.capacity);
    }
    if (!isMockUnplugged_) {
        batteryInfo_.SetPluggedType(BatteryPluggedType(event.pluggedType));
        batteryInfo_.SetPluggedMaxCurrent(event.pluggedMaxCurrent);
        batteryInfo_.SetPluggedMaxVoltage(event.pluggedMaxVoltage);
        batteryInfo_.SetChargeState(BatteryChargeState(event.chargeState));
    }
    batteryInfo_.SetVoltage(event.voltage);
    batteryInfo_.SetTemperature(event.temperature);
    batteryInfo_.SetHealthState(BatteryHealthState(event.healthState));
    batteryInfo_.SetChargeCounter(event.chargeCounter);
    batteryInfo_.SetTotalEnergy(event.totalEnergy);
    batteryInfo_.SetCurAverage(event.curAverage);
    batteryInfo_.SetRemainEnergy(event.remainEnergy);
    batteryInfo_.SetPresent(event.present);
    batteryInfo_.SetTechnology(event.technology);
    batteryInfo_.SetNowCurrent(event.curNow);
    batteryInfo_.SetChargeType(GetChargeType());
}

void BatteryService::HandleBatteryInfo()
{
    BATTERY_HILOGD(FEATURE_BATT_INFO, "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, currNow=%{public}d, totalEnergy=%{public}d, curAverage=%{public}d, "
        "remainEnergy=%{public}d, chargeType=%{public}d", batteryInfo_.GetCapacity(), batteryInfo_.GetVoltage(),
        batteryInfo_.GetTemperature(), batteryInfo_.GetHealthState(), batteryInfo_.GetPluggedType(),
        batteryInfo_.GetPluggedMaxCurrent(), batteryInfo_.GetPluggedMaxVoltage(), batteryInfo_.GetChargeState(),
        batteryInfo_.GetChargeCounter(), batteryInfo_.IsPresent(), batteryInfo_.GetTechnology().c_str(),
        batteryInfo_.GetNowCurrent(), batteryInfo_.GetTotalEnergy(), batteryInfo_.GetCurAverage(),
        batteryInfo_.GetRemainEnergy(), batteryInfo_.GetChargeType());

    batteryLight_.UpdateColor(batteryInfo_.GetChargeState(), batteryInfo_.GetCapacity());
   
    // 若有外接电源插入/拔出,则唤醒设备
    WakeupDevice(batteryInfo_.GetPluggedType());
   
    // 根据batteryInfo_,更新
    CalculateRemainingChargeTime(batteryInfo_.GetCapacity(), batteryInfo_.GetChargeState());
   
    // BatteryNotify 发布电池信息更新事件
    batteryNotify_->ublishEvents(batteryInfo_);
    //其他信息更新
    HandleTemperature(batteryInfo_.GetTemperature());
    HandleCapacity(batteryInfo_.GetCapacity(), batteryInfo_.GetChargeState());
    lastBatteryInfo_ = batteryInfo_;
}

// PublishEvents此处不一一解读
int32_t BatteryNotify:ublishEvents(const BatteryInfo& info)
{
    if (g_commonEventInitSuccess) {
        BATTERY_HILOGI(COMP_SVC, "common event service ability init success");
    } else {
        if (!IsCommonEventServiceAbilityExist()) {
            return ERR_NO_INIT;
        }
    }

    bool isAllSuccess = true;
    bool ret = PublishChangedEvent(info);
    isAllSuccess &= ret;
    ret = PublishChangedEventInner(info);
    isAllSuccess &= ret;
    ret = PublishLowEvent(info);
    isAllSuccess &= ret;
    ret = PublishOkayEvent(info);
    isAllSuccess &= ret;
    ret = PublishPowerConnectedEvent(info);
    isAllSuccess &= ret;
    ret = PublishPowerDisconnectedEvent(info);
    isAllSuccess &= ret;
    ret = PublishChargingEvent(info);
    isAllSuccess &= ret;
    ret = PublishDischargingEvent(info);
    isAllSuccess &= ret;
    ret = PublishChargeTypeChangedEvent(info);
    isAllSuccess &= ret;

    return isAllSuccess ? ERR_OK : ERR_NO_INIT;
}
```

## 显示控制组件

显示管理组件主要负责显示屏的亮/灭、亮度调节等功能,如下:

1. 显示屏的亮/灭。
2. 显示屏亮度调节。

### 设置屏幕亮度接口

function setValue(value: number): void;

```js
@throws {BusinessError} 401 - If the value is not valid.
@throws {BusinessError} 4700101 - If connecting to the service failed.
```

| 参数名 | 类型   | 必填 | 说明              |
| ------ | ------ | ---- | ----------------- |
| value  | number | 是   | 亮度的值(0~255) |

示例:

```js
import brightness from '@ohos.brightness.d.ts'
brightness.setValue(128);
```

### 代码目录

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

### Display Manager Service服务启动

Display Manager Service服务被打包到foundation进程,启动过程基本同电池服务(Battery Service)的启动,详细启动流程可以看System Ability管理相关的资料。

注册信息:

```json
{
    "process": "foundation",
    "systemability": [
        {
            "name": 3308,
            "libpath": "libdisplaymgrservice.z.so",
            "run-on-create": true,
            "distributed": false,
            "dump_level": 1
        }
    ]
}
```

注册代码:

```c++
REGISTER_SYSTEM_ABILITY_BY_ID(DisplaySystemAbility, DISPLAY_MANAGER_SERVICE_ID, true);
//宏定义展开,调用SystemAbility接口注册DisplayManagerService实例
#define REGISTER_SYSTEM_ABILITY_BY_ID(abilityClassName, systemAbilityId, runOnCreate) \
    const bool abilityClassName##_##RegisterResult = \
    SystemAbility::MakeAndRegisterAbility(new abilityClassName(systemAbilityId, runOnCreate));
```

System Ability管理模块调用DisplaySystemAbility的启动函数实现显示控制服务组件的启动:

```c++
//此处与电池管理服务不同,是把DisplayMgrService的对象实例发布到System Ability管理模块
void DisplaySystemAbility::OnStart() override
{
    DISPLAY_HILOGI(COMP_SVC, "DisplayPowerService On Start.");
   
    // 监听DISPLAY_MANAGER_SERVICE_SA_ID,当监听到该服务publish到SAmgr里面后,就会触发OnAddSystemAbility
    AddSystemAbilityListener(DISPLAY_MANAGER_SERVICE_SA_ID);
}

// override基类方法,当依赖的service发布后,再进行DisplayPowerMgrService的发布
void DisplaySystemAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override
{
    if (systemAbilityId == DISPLAY_MANAGER_SERVICE_SA_ID) {
        DISPLAY_HILOGI(COMP_SVC, "Start service");
        
        // DisplayPowerMgrService 实例
        auto service = DelayedSpSingleton<DisplayPowerMgrService>::GetInstance();
        // Init
        service->Init();
        if (!Publish(service)) {
            DISPLAY_HILOGE(COMP_SVC, "Failed to publish service");
        }
    }
}

void DisplayPowerMgrService::Init()
{
    DISPLAY_HILOGI(COMP_SVC, "DisplayPowerMgrService Create");
   
    // 通过ScreenAction::GetAllDisplayId(),获取所有displayIds,
    // 并初始化std::map<uint64_t, std::shared_ptr<ScreenController>> controllerMap_;
    // 其中, ScreenAction/ScreenController的初始化和用到的方法的细节,本篇不做过多的解读
    std::vector<uint32_t> displayIds = ScreenAction::GetAllDisplayId();
    for (const auto& id: displayIds) {
        DISPLAY_HILOGI(COMP_SVC, "find display, id=%{public}u", id);
        controllerMap_.emplace(id, std::make_shared<ScreenController>(id));
    }
   
    callback_ = nullptr;
    cbDeathRecipient_ = nullptr;
#ifdef HAS_SENSORS_SENSOR_PART
    InitSensors();  // 若有sensor,将进行Sensors的初始化,细节本篇不做过多的解读
#endif
    // 注册/初始化DisplayPowerMgrService的必要回调函数
    RegisterBootCompletedCallback();
}

// 根据不同的displayId,生成对应ScreenController实例,
// 每个ScreenController实例,拥有各自的ScreenAction和 animateCallback_
ScreenController::ScreenController(uint32_t displayId)
{
    DISPLAY_HILOGI(COMP_SVC, "ScreenController created for displayId=%{public}u", displayId);
    action_ = make_shared<ScreenAction>(displayId);
    state_ = action_->GetDisplayState();

    string name = "BrightnessController_" + to_string(displayId);
    if (animateCallback_ == nullptr) {
        animateCallback_ = make_shared<AnimateCallbackImpl>(action_, [this](uint32_t brightness) {
            SetSettingBrightness(brightness);
        });
    }
    animator_ = make_shared<GradualAnimator>(name, animateCallback_);
}

//Tips:限于篇幅,具体的初始化细节不在本篇过多展开,后续系列文章将详细描述
```

### 设置屏幕亮度流程

流程图:
![setdiplayLight.png](data/attachment/forum/202310/20/150504yjs50hd8t58h4g65.png "setdiplayLight .png")

代码:

```c++
//brightness_module: setValue
// import brightness from '@ohos.brightness';
// brightness.setValue
static napi_value SetValue(napi_env env, napi_callback_info info)
{
    napi_value res = SyncWork(
        env,
        "SetValue",
        Brightness::BRIGHTNESS_VALUE,
        info,
        [](napi_env env, napi_status status, void *data) {
            Brightness *asyncBrightness = reinterpret_cast<Brightness*>(data);
            if (asyncBrightness != nullptr) {
                // 异步调用Brightness::SystemSetValue()
                asyncBrightness->SystemSetValue();
                napi_delete_async_work(env, asyncBrightness->asyncWork);
                delete asyncBrightness;
            }
        }
    );
   
    // 若失败,调用Brightness::SetValue(...)
    if (res != nullptr) {
        Brightness brightness(env);
        // 调用SetValue(...)
        brightness.SetValue(info);
        OHOS::HiviewDFX::ReportXPowerJsStackSysEvent(env, "Brightness::SetValue");
    }
    return nullptr;
}

void Brightness::SystemSetValue()
{
    DISPLAY_HILOGD(FEAT_BRIGHTNESS, "System brightness interface");
    if (napiValRef_ == nullptr) {
        result_.Error(INPUT_ERROR_CODE, SET_VALUE_ERROR_MGR);
    } else {
        int32_t brightness = MIN_BRIGHTNESS;
        napi_value napiVal = nullptr;
        napi_get_reference_value(env_, napiValRef_, &napiVal);
        napi_get_value_int32(env_, napiVal, &brightness);
        // 调用Brightness::BrightnessInfo::SetBrightness(...)
        brightnessInfo_.SetBrightness(brightness, false);
        ReleaseReference(napiValRef_);
    }
    ExecuteCallback();
}
or:
void Brightness::SetValue(napi_callback_info& info)
{
    DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Brightness interface");
   
    // NAPI参数格式转换为c++格式
    napi_value napiBrightness = GetCallbackInfo(info, ARGV_BRIGHTNESS_INDEX, napi_number);
    napi_value napiUndefined = GetCallbackInfo(info, ARGV_BRIGHTNESS_INDEX, napi_undefined);
    if (napiBrightness == nullptr && napiUndefined == nullptr) {
        result_.ThrowError(env_, DisplayErrors::ERR_PARAM_INVALID);
        return;
    }
     
    int32_t value = MIN_BRIGHTNESS;
    bool continuous = false;
    // int 转换
    if (napi_get_value_int32(env_, napiBrightness, &value) != napi_ok) {
        if (napiUndefined != nullptr) {
            return;
        } else {
            DISPLAY_HILOGW(COMP_FWK, "Failed to get the input number");
            result_.ThrowError(env_, DisplayErrors::ERR_PARAM_INVALID);
            return;
        }
    }
    napi_value napiContinuous = GetCallbackInfo(info, ARGV_CONTINUOUS_INDEX, napi_boolean);
    if (napiContinuous != nullptr) {
        // bool 转换
        napi_get_value_bool(env_, napiContinuous, &continuous);
    }
   
    // 调用Brightness::BrightnessInfo::SetBrightness(...)
    if (!brightnessInfo_.SetBrightness(value, continuous)) {
        DisplayErrors error = brightnessInfo_.GetServiceError();
        if (error != DisplayErrors::ERR_OK) {
            result_.ThrowError(env_, error);
        }
    }
}

bool Brightness::BrightnessInfo::SetBrightness(int32_t value, bool continuous)
{
    DISPLAY_HILOGI(FEAT_BRIGHTNESS, "Set brightness: %{public}d", value);
    value = value > static_cast<int32_t>(MAX_BRIGHTNESS) ? static_cast<int32_t>(MAX_BRIGHTNESS) : value;
    value = value < static_cast<int32_t>(MIN_BRIGHTNESS) ? static_cast<int32_t>(MIN_BRIGHTNESS) : value;
    bool isSucc = DisplayPowerMgrClient::GetInstance().SetBrightness(value, 0, continuous);
    if (!isSucc) {
        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Failed to set brightness: %{public}d", value);
    }
    return isSucc;
}

bool DisplayPowerMgrClient::SetBrightness(uint32_t value, uint32_t displayId, bool continuous)
{
    auto proxy = GetProxy();
    RETURN_IF_WITH_RET(proxy == nullptr, false);
   
    //这里需要了解SystemAbility IPC机制:xxClient-->xxProxy-->xxStub-->xxService。
    //根据DISPLAY_MANAGER_SERVICE_ID查到 DisplayPowerMgrService 服务能力
    //最终将调用DisplayPowerMgrService::SetBrightness
    return proxy->SetBrightness(value, displayId, continuous);
}

bool DisplayPowerMgrService::SetBrightness(uint32_t value, uint32_t displayId, bool continuous)
{
    if (!Permission::IsSystem()) {
        lastError_ = DisplayErrors::ERR_SYSTEM_API_DENIED;
        return false;
    }

    auto brightness = GetSafeBrightness(value);
    DISPLAY_HILOGI(FEAT_BRIGHTNESS, "SetBrightness displayId=%{public}u, value=%{public}u, continuous=%{public}d",
        displayId, brightness, continuous);
    auto iter = controllerMap_.find(displayId);
    if (iter == controllerMap_.end()) {
        return false;
    }
    //调用 ScreenController::SetBrightness,注意第2个参数为0
    return iter->second->SetBrightness(brightness, 0, continuous);
}

bool ScreenController::SetBrightness(uint32_t value, uint32_t gradualDuration, bool continuous)
{
    // 判断当前是否适合进行亮度设置
    if (!CanSetBrightness()) {
        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "Cannot set brightness, ignore the change,"\
            "cachedSettingBrightness_ %{public}u -> %{public}u", cachedSettingBrightness_.load(), value);
        cachedSettingBrightness_ = value;
        return false;
    }
    // 调用 ScreenController::UpdateBrightness(),更新Brightness
    return UpdateBrightness(value, gradualDuration, !continuous);
}

bool ScreenController::UpdateBrightness(uint32_t value, uint32_t gradualDuration, bool updateSetting)
{
    DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Update brightness, value=%{public}u, discount=%{public}lf,"\
                   " duration=%{public}u, updateSetting=%{public}d", value, discount_, gradualDuration, updateSetting);

    if (animator_->IsAnimating()) {
        animator_->StopAnimation();
    }
   
    // 入参gradualDuration =0,此处不执行,继续后面的代码
    if (gradualDuration > 0) {
        animator_->StartAnimation(GetSettingBrightness(), value, gradualDuration);
        return true;
    }
    auto brightness = DisplayPowerMgrService::GetSafeBrightness(static_cast<uint32_t>(value * discount_));
    //调用ScreenAction::SetBrightness
    bool isSucc = action_->SetBrightness(brightness);
    DISPLAY_HILOGD(FEAT_BRIGHTNESS, "Updated brightness is %{public}s, brightness: %{public}u",
                   isSucc ? "succ" : "failed", brightness);
    // 成功后且需要更新数据库(updateSetting 为true)cache,ScreenController::SetSettingBrightness
    if (isSucc && updateSetting) {
        FFRTUtils::SubmitTask(std::bind(&ScreenController::SetSettingBrightness, this, value));
    }
    return isSucc;
}

bool ScreenAction::SetBrightness(uint32_t value)
{
    DISPLAY_HILOGD(FEAT_BRIGHTNESS, "displayId=%{public}u, brightness=%{public}u", displayId_, value);
    // Notify screen brightness change event to battery statistics
    HiSysEventWrite(HiviewDFX::HiSysEvent:omain:ISPLAY, "BRIGHTNESS_NIT",
        HiviewDFX::HiSysEvent::EventType::STATISTIC, "BRIGHTNESS", value);
    std::string identity = IPCSkeleton::ResetCallingIdentity();
    // 调用 Rosen:isplayManager::SetScreenBrightness
    // ./foundation/window/window_manager/interfaces/innerkits/dm/display_manager.h
    bool isSucc = Rosen:isplayManager::GetInstance().SetScreenBrightness(displayId_, value);
    IPCSkeleton::SetCallingIdentity(identity);
    std::lock_guard lock(mutexBrightness_);
    brightness_ = isSucc ? value : brightness_;
    return isSucc;
}

void ScreenController::SetSettingBrightness(uint32_t value)
{
    // 更新数据库和cache值
    DisplaySettingHelper::SetSettingBrightness(value);
    cachedSettingBrightness_ = value;
    DISPLAY_HILOGD(FEAT_BRIGHTNESS, "set setting brightness=%{public}u", value);
}

void DisplaySettingHelper::SetSettingBrightness(uint32_t value)
{
    uint32_t settingBrightness;
    if (GetSettingBrightness(settingBrightness) != ERR_OK) {
        return;
    }
    if (value == static_cast<uint32_t>(settingBrightness)) {
        DISPLAY_HILOGD(FEAT_BRIGHTNESS, "no need to set setting brightness");
        return;
    }
    // 更新数据库
    SettingProvider& provider = SettingProvider::GetInstance(DISPLAY_MANAGER_SERVICE_ID);
    auto ret = provider.PutIntValue(SETTING_BRIGHTNESS_KEY, static_cast<int32_t>(value));
    if (ret != ERR_OK) {
        DISPLAY_HILOGW(FEAT_BRIGHTNESS, "set setting brightness failed, ret=%{public}d", ret);
        return;
    }
    DISPLAY_HILOGD(FEAT_BRIGHTNESS, "set setting brightness=%{public}u", value);
}
```

## 电源管理服务组件

电源管理服务组件提供如下功能:

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

### 系统电源管理接口

接口使用所需权限:

1. 关机权限: ohos.permission.SHUTDOWN
2. 重启权限: ohos.permission.REBOOT
3. 重启并进入recovery模式的权限:ohos.permission.REBOOT_RECOVERY

**系统关机**:power.shutdown

​        function shutdown(reason: string): void;

参数:

| 参数名 | 类型   | 必填 | 说明       |
| ------ | ------ | ---- | ---------- |
| reason | string | 是   | 关机原因。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**重启设备**:power.reboot

​        function reboot(reason: string): void;

参数:

| 参数名 | 类型   | 必填 | 说明       |
| ------ | ------ | ---- | ---------- |
| reason | string | 是   | 重启原因。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**检测当前设备是否处于活动状态:**有屏的设备为亮屏状态,无屏的设备为非休眠状态。

​          function isActive(): boolean

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**唤醒设备:**        power.wakeup

​        function wakeup(detail: string): void

参数:

| 参数名 | 类型   | 必填 | 说明       |
| ------ | ------ | ---- | ---------- |
| detail | string | 是   | 唤醒原因。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**休眠设备:**        power.suspend

​    function suspend(isImmediate?: boolean): void

参数:

| 参数名         | 类型    | 必填 | 说明                                                         |
| -------------- | ------- | ---- | ------------------------------------------------------------ |
| isImmediate10+ | boolean | 否   | 是否直接休眠设备。不填该参数则默认为false由系统自动检测何时进入休眠。 **说明:** 从API version 10开始,支持该参数。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**获取当前设备的电源模式:**        power.getPowerMode

​    function getPowerMode(): DevicePowerMode

返回值:

| 类型            | 说明       |
| --------------- | ---------- |
| DevicePowerMode | 电源模式。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**设置当前设备的电源模式。使用callback异步回调:**        power.setPowerMode

​    function setPowerMode(mode: DevicePowerMode, callback: AsyncCallback<void>): void

参数:

| 参数名   | 类型                | 必填 | 说明                                                         |
| -------- | ------------------- | ---- | ------------------------------------------------------------ |
| mode     | DevicePowerMode     | 是   | 电源模式。                                                   |
| callback | AsyncCallback | 是   | 回调函数。当设置电源模式成功,err为undefined,否则为错误对象。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**设置当前设备的电源模式。使用Promise异步回调:**        power.setPowerMode

​    function setPowerMode(mode: DevicePowerMode): Promise<void>

参数:

| 参数名 | 类型            | 必填 | 说明       |
| ------ | --------------- | ---- | ---------- |
| mode   | DevicePowerMode | 是   | 电源模式。 |

返回值:

| 类型          | 说明                                   |
| ------------- | -------------------------------------- |
| Promise | Promise对象。无返回结果的Promise对象。 |

**检测当前设备是否进入待机低功耗续航模式:**        power.isStandby

​    function isStandby(): boolean

返回值:

| 类型    | 说明                                  |
| ------- | ------------------------------------- |
| boolean | 进入待机模式返回true,否则返回false。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**表示电源模式的枚举值:**        DevicePowerMode

| 名称                    | 值   | 说明                   |
| ----------------------- | ---- | ---------------------- |
| MODE_NORMAL             | 600  | 表示标准模式,默认值。 |
| MODE_POWER_SAVE         | 601  | 表示省电模式。         |
| MODE_PERFORMANCE        | 602  | 表示性能模式。         |
| MODE_EXTREME_POWER_SAVE | 603  | 表示超级省电模式。     |

### Runninglock锁接口

接口使用所需权限:ohos.permission.RUNNING_LOCK

**RunningLock锁的类型:**

| 名称                     | 默认值 | 描述                                                         |
| ------------------------ | ------ | ------------------------------------------------------------ |
| BACKGROUND               | 1      | 阻止系统休眠的锁。**说明:** 从API version 7开始支持,从API version 10开始废弃。 |
| PROXIMITY_SCREEN_CONTROL | 2      | 通过接近或者远离状态来控制亮灭屏的锁。                       |

**查询系统是否支持该类型的锁:**

​    function isSupported(type: RunningLockType): boolean;

参数:

| 参数名 | 类型            | 必填 | 说明                 |
| ------ | --------------- | ---- | -------------------- |
| type   | RunningLockType | 是   | 需要查询的锁的类型。 |

返回值:

| 类型    | 说明                                    |
| ------- | --------------------------------------- |
| boolean | 返回true表示支持,返回false表示不支持。 |

**创建RunningLock锁之一:**

​        function create(name: string, type: RunningLockType, callback: AsyncCallback<RunningLock>): void

参数:

| 参数名   | 类型                       | 必填 | 说明                                                         |
| -------- | -------------------------- | ---- | ------------------------------------------------------------ |
| name     | string                     | 是   | 锁的名字。                                                   |
| type     | RunningLockType            | 是   | 要创建的锁的类型。                                           |
| callback | AsyncCallback | 是   | 回调函数。当创建锁成功,err为undefined,data为创建的RunningLock;否则为错误对象。 |

**创建Runninglock锁之二:**

​    function create(name: string, type: RunningLockType): Promise<RunningLock>

- 参数:
  
  | 参数名 | 类型            | 必填 | 说明               |
| ------ | --------------- | ---- | ------------------ |
| name   | string          | 是   | 锁的名字。         |
| type   | RunningLockType | 是   | 要创建的锁的类型。 |
  
  
- 返回值:
  
  | 类型                 | 说明                                 |
| -------------------- | ------------------------------------ |
| Promise | Promise对象,返回RunningLock锁对象。 |
  
  

**锁定和持有RunningLock:**

​        function hold(timeout: number): void

参数:

| 参数名  | 类型   | 必填 | 说明                                    |
| ------- | ------ | ---- | --------------------------------------- |
| timeout | number | 否   | 锁定和持有RunningLock的时长。单位:毫秒 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**释放Runninglock锁:**

​        function unhold(): void

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

**查询当前Runninglock是持有状态,还是释放状态:**

​        function isHolding(): boolean

返回值:

| 类型    | 说明                                                   |
| ------- | ------------------------------------------------------ |
| boolean | 当前RunningLock是持有状态返回true,释放状态返回false。 |

错误码:

| 错误码ID | 错误信息                             |
| -------- | ------------------------------------ |
| 4900101  | If connecting to the service failed. |

### 代码目录

```
/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 Manager Service服务启动

Power Manager Service服务被打包到foundation进程,启动过程基本同电池服务(Battery Service)的启动,详细启动流程可以看System Ability管理相关的资料。

注册信息:

```json
{
    "process": "foundation",
    "systemability": [
        {
            "name": 3301,
            "libpath": "libpowermgrservice.z.so",
            "run-on-create": true,
            "distributed": false,
            "dump_level": 1
        }
    ]
}
```

注册代码:

```c++
auto pms = DelayedSpSingleton<owerMgrService>::GetInstance();
//调用SystemAbility接口注册BatteryService实例
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(pms.GetRefPtr());

//构建入参为serviceid、runoncreate
PowerMgrService:owerMgrService() : SystemAbility(POWER_MANAGER_SERVICE_ID, true) {}
```

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

```c++
void PowerMgrService::OnStart()
{
    POWER_HILOGD(COMP_SVC, "ower Management startup");
    if (ready_) {
        POWER_HILOGW(COMP_SVC, "OnStart is ready, nothing to do");
        return;
    }
    if (!Init()) {
        POWER_HILOGE(COMP_SVC, "Call init fail");
        return;
    }
   
    // 监听特定的SA是否已publish到SAmgr
    AddSystemAbilityListener(SUSPEND_MANAGER_SYSTEM_ABILITY_ID);
    AddSystemAbilityListener(DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID);
   
    // RegisterHdiStatusListener: 设置系统休眠的相关回调,限于篇幅,此处不做过多的展开
    SystemSuspendController::GetInstance().RegisterHdiStatusListener();
   
    //PowerMgrService服务发布到System Ability管理模块
    if (!Publish(DelayedSpSingleton<owerMgrService>::GetInstance())) {
        POWER_HILOGE(COMP_SVC, "Register to system ability manager failed");
        return;
    }
    //设置已启动
    ready_ = true;
    POWER_HILOGI(COMP_SVC, "Add system ability success");
}

bool PowerMgrService::Init()
{
    POWER_HILOGI(COMP_SVC, "Init start");
   
     //创建RunningLockMgr实例
    if (!runningLockMgr_) {
        runningLockMgr_ = std::make_shared<RunningLockMgr>(pms);
    }
   
    // 执行RunningLockMgr的Init初始化,并创建RunningLockAction实例
    if (!runningLockMgr_->Init()) {
        POWER_HILOGE(COMP_SVC, "Running lock init fail");
        return false;
    }
   
    // 初始化shutdownController_
    if (!shutdownController_) {
        shutdownController_ = std::make_shared<ShutdownController>();
    }
   
    //创建PowerStateMachine实例,执行PowerStateMachine的Init初始化,并创建DeviceStateAction实例
    if (!PowerStateMachineInit()) {
        POWER_HILOGE(COMP_SVC, "ower state machine init fail");
    }
   
    // BootCompleted后的进行注册回调
    RegisterBootCompletedCallback();
    POWER_HILOGI(COMP_SVC, "Init success");
    return true;
}


bool PowerMgrService:owerStateMachineInit()
{
    if (powerStateMachine_ == nullptr) {
        powerStateMachine_ = std::make_shared<owerStateMachine>(pms);
        
        // 初始化powerStateMachine:创建DeviceStateAction,初始化状态转换时对应的function及死亡回调
        if (!(powerStateMachine_->Init())) {
            POWER_HILOGE(COMP_SVC, "ower state machine start fail!");
            return false;
        }
    }
   
    // 初始化电源管理通知:powerMgrNotify_: CommonEventPublishInfo/screenOffWant_/screenOffWant_
    if (powerMgrNotify_ == nullptr) {
        powerMgrNotify_ = std::make_shared<owerMgrNotify>();
        powerMgrNotify_->RegisterPublishEvents();
    }
    return true;
}
        
// 注册回调,限于篇幅,不做一一展开。   
void PowerMgrService::RegisterBootCompletedCallback()
{
    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();
        powerStateMachine->RegisterDisplayOffTimeObserver();
        powerStateMachine->InitState();
        power->GetShutdownDialog().KeyMonitorInit();
        power->HallSensorSubscriberInit();
        power->SwitchSubscriberInit();
        power->SuspendControllerInit();
        power->WakeupControllerInit();
        power->VibratorInit();
        isBootCompleted_ = true;
    };
     
    WakeupRunningLock::Create();
    SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
}
```

### 系统电源管理接口调用流程

以shutdown为例解析接口调用流程,其它接口除了功能差异,流程都差不多。

代码:

```c++
import power from '@ohos.power';
power.shutdown("shutdown_test");
static napi_value PowerNapi::Shutdown(napi_env env, napi_callback_info info)
{
    return RebootOrShutdown(env, info, false);
}

napi_value PowerNapi::RebootOrShutdown(napi_env env, napi_callback_info info, bool isReboot)
{
    size_t argc = REBOOT_SHUTDOWN_MAX_ARGC;
    napi_value argv[argc];
    NapiUtils::GetCallbackInfo(env, info, argc, argv);

    // 读取并检查入参,判断是shutdown or RebootDevice 操作
    NapiErrors error;
    if (argc != REBOOT_SHUTDOWN_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string)) {
        return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
    }

    std::string reason = NapiUtils::GetStringFromNapi(env, argv[INDEX_0]);
    POWER_HILOGD(FEATURE_SHUTDOWN, "reboot: %{public}d, reason: %{public}s", isReboot, reason.c_str());
   
    PowerErrors code;
    if (isReboot) {
        code = g_powerMgrClient.RebootDevice(reason);
    } else {
        // isReboot为false,调用g_powerMgrClient.ShutDownDevice(std::string(reason));
        //查找POWER_MANAGER_SERVICE_ID,即上面注册的PowerMgrService服务
        //这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxStub-->xxService。
        code = g_powerMgrClient.ShutDownDevice(reason);
    }
    if (code != PowerErrors::ERR_OK) {
        error.ThrowError(env, code);
    }
    return nullptr;
}


PowerErrors PowerMgrService::ShutDownDevice(const std::string& reason)
{
    auto now = static_cast<int64_t>(time(nullptr));
    if (!Permission::IsSystem()) {
        return PowerErrors::ERR_SYSTEM_API_DENIED;
    }
    if (!Permission::IsPermissionGranted("ohos.permission.REBOOT")) {
        return PowerErrors::ERR_PERMISSION_DENIED;
    }
    if (reason == SHUTDOWN_FAST_REASON) {
        g_wakeupReason = reason;
        POWER_HILOGD(FEATURE_SHUTDOWN, "Calling Fast ShutDownDevice success");
        return SuspendDevice(now, SuspendDeviceType::SUSPEND_DEVICE_REASON_STR, true);
    }
    g_wakeupReason = "";
    std::lock_guard lock(shutdownMutex_);
    pid_t pid = IPCSkeleton::GetCallingPid();
    auto uid = IPCSkeleton::GetCallingUid();
   
    // 取消自动休眠相关定时器
    POWER_HILOGI(FEATURE_SHUTDOWN, "Cancel auto sleep timer");
    powerStateMachine_->CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_TIMEOUT_MSG);
    powerStateMachine_->CancelDelayTimer(PowerStateMachine::CHECK_USER_ACTIVITY_OFF_TIMEOUT_MSG);
   
    // 停止休眠 StopSleep
    if (suspendController_) {
        suspendController_->StopSleep();
    }

    POWER_HILOGI(FEATURE_SHUTDOWN, "Do shutdown, called pid: %{public}d, uid: %{public}d", pid, uid);
    // 调用ShutdownController::ShutDownDevice
    shutdownController_->Shutdown(reason);
    return PowerErrors::ERR_OK;
}

void ShutdownController::Shutdown(const std::string& reason)
{
    RebootOrShutdown(reason, false);
}

void ShutdownController::RebootOrShutdown(const std::string& reason, bool isReboot)
{
    if (started_) {
        POWER_HILOGW(FEATURE_SHUTDOWN, "Shutdown is already running");
        return;
    }
    started_ = true;
    bool isTakeOver = TriggerTakeOverShutdownCallback(isReboot);
    if (isTakeOver) {
        started_ = false;
        return;
    }
   
    // shutdown的相关处理:事件分发/触发回调/关闭屏幕
    POWER_HILOGI(FEATURE_SHUTDOWN, "Start to detach shutdown thread");
    PublishShutdownEvent();
    TriggerSyncShutdownCallback();
    TurnOffScreen();
    // 开启线程do
    make_unique<thread>([=] {
        //等待回调事件完成
        Prepare();
        POWER_HILOGD(FEATURE_SHUTDOWN, "reason = %{public}s, reboot = %{public}d", reason.c_str(), isReboot);

#ifdef POWER_MANAGER_POWEROFF_CHARGE
        if (IsNeedWritePoweroffChargeFlag()) {
            WritePoweroffChargeFlag();
        }
#endif
        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(FEATURE_SHUTDOWN, "Shutdown executing");
    // ./base/startup/init/interfaces/innerkits/include/init_reboot.h
    // 调用init_reboot的DoReboot(...)
    DoReboot(SHUTDOWN_CMD.c_str());
}
```

### 系统休眠锁接口调用流程

在PowerMgrService服务启动初始化节点创建了RunningLockMgr的管理实例,接口调用流程和电源管理接口基本上差不多,实现系统休眠锁的核心原理如下:

1. 加锁的sysfs文件:/sys/power/wake_lock,用户程序向文件写入一个字符串,即可创建一个wakelock,该字符串就是wakelock的名字。该wakelock可以阻止系统进入低功耗模式。
2. 解锁的sysfs文件::/sys/power/wake_unlock,用户程序向文件写入相同的字符串,即可注销一个wakelock。
3. 当系统中所有的wakelock都注销后,系统可以自动进入低功耗状态。

代码:

```c++
import runningLock from '@ohos.runningLock';
...
runningLock.create('running_lock_test', runningLock.RunningLockType.BACKGROUND)
.then((lock: runningLock.RunningLock) => {
    try {
        lock.hold(500);
    } catch(err) {
        console.error('hold running lock failed, err: ' + err);
    }
})
.catch((err: { code: number, message: string }) => {
    console.error('create running lock failed, err: ' + err);
});

napi_value RunningLockInterface:ock(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1] = {0};
    napi_value thisArg = nullptr;
    void* data = nullptr;

    napi_status status = napi_get_cb_info(env, info, &argc, args, &thisArg, &data);
    NAPI_ASSERT(env, (status == napi_ok) && (argc >= 1), "Failed to get cb info");
    napi_valuetype type = napi_undefined;
    NAPI_CALL(env, napi_typeof(env, args[0], &type));
    NAPI_ASSERT(env, type == napi_number, "Wrong argument type. number expected.");

    int32_t timeOut;
    status = napi_get_value_int32(env, args[0], &timeOut);
    if (status != napi_ok) {
        POWER_HILOGE(FEATURE_RUNNING_LOCK, "napi_get_value_uint32 failed");
        return nullptr;
    }
    // RunningLockEntity结构体指针
    RunningLockEntity* entity = nullptr;
    status = napi_unwrap(env, thisArg, (void**)&entity);
    if (status != napi_ok) {
        POWER_HILOGE(FEATURE_RUNNING_LOCK, "Cannot unwrap for pointer");
        return nullptr;
    }
    if (entity == nullptr || entity->runningLock == nullptr) {
        POWER_HILOGE(FEATURE_RUNNING_LOCK, "Entity runningLock is nullptr");
        return nullptr;
    }
    // 调用RunningLock:ock(...)
    entity->runningLock->Lock(timeOut);
    OHOS::HiviewDFX::ReportXPowerJsStackSysEvent(env, "RunningLockNapi:ock");
    return nullptr;
}
-------------------------------------------------------------------
struct RunningLockEntity {
    std::shared_ptr<RunningLock> runningLock = nullptr;
}
-------------------------------------------------------------------
ErrCode RunningLock:ock(int32_t timeOutMs)
{
    POWER_HILOGD(FEATURE_RUNNING_LOCK, "Lock timeOutMs: %{public}u", timeOutMs);

     //查找POWER_MANAGER_SERVICE_ID,即上面注册的PowerMgrService服务
     //这里需要了解SystemAbility IPC机制:xxProxy-->xxStub-->xxService。
    // RunningLock用的是PowerMgrService的服务
    sptr<IPowerMgr> proxy = proxy_.promote();
    if (proxy == nullptr) {
        POWER_HILOGE(FEATURE_RUNNING_LOCK, "Proxy is a null pointer");
        return E_GET_POWER_SERVICE_FAILED;
    }
    POWER_HILOGD(FEATURE_RUNNING_LOCK, "Service side Lock call");
    proxy->Lock(token_, timeOutMs);

    return ERR_OK;
}

// 调用PowerMgrService:ock
bool PowerMgrService:ock(const sptr<IRemoteObject>& remoteObj, int32_t timeOutMS)
{
    std::lock_guard lock(lockMutex_);
    if (!Permission::IsPermissionGranted("ohos.permission.RUNNING_LOCK")) {
        return false;
    }

    POWER_HILOGI(FEATURE_RUNNING_LOCK, "timeOutMS: %{public}d", timeOutMS);
    // 调用RunningLockMgr:ock
    runningLockMgr_->Lock(remoteObj, timeOutMS);
    return true;
}

void RunningLockMgr:ock(const sptr<IRemoteObject>& remoteObj, int32_t timeOutMS)
{
    StartTrace(HITRACE_TAG_POWER, "RunningLock_Lock");

    // lock有效性判断
    auto lockInner = GetRunningLockInner(remoteObj);
    if (lockInner == nullptr) {
        POWER_HILOGE(FEATURE_RUNNING_LOCK, "LockInner is nullptr");
        return;
    }
    if (lockInner->IsProxied()) {
        POWER_HILOGW(FEATURE_RUNNING_LOCK, "Runninglock is proxied");
        return;
    }
    if (runninglockProxy_->IsProxied(lockInner->GetPid(), lockInner->GetUid())) {
        POWER_HILOGW(FEATURE_RUNNING_LOCK, "Runninglock is proxied, do not allow lock");
        return;
    }
   
    // 设置lock的时间
    lockInner->SetTimeOutMs(timeOutMS);
    RunningLockParam lockInnerParam = lockInner->GetParam();
    POWER_HILOGD(FEATURE_RUNNING_LOCK, "name=%{public}s, type=%{public}d, timeoutMs=%{public}d",
        lockInnerParam.name.c_str(), lockInnerParam.type, timeOutMS);
   
    // RunningLockAction::Lock
    if (IsSceneRunningLockType(lockInnerParam.type)) {
        runningLockAction_->Lock(lockInnerParam);
        NotifyRunningLockChanged(remoteObj, lockInner, NOTIFY_RUNNINGLOCK_ADD);
        return;
    }

    if (lockInner->GetState() == RunningLockState::RUNNINGLOCK_STATE_ENABLE) {
        POWER_HILOGD(FEATURE_RUNNING_LOCK, "Lock is already enabled");
        return;
    }
    auto iterator = lockCounters_.find(lockInnerParam.type);
    if (iterator == lockCounters_.end()) {
        POWER_HILOGE(FEATURE_RUNNING_LOCK, "Lock failed unsupported type, type=%{public}d", lockInnerParam.type);
        return;
    }
    lockInner->SetState(RunningLockState::RUNNINGLOCK_STATE_ENABLE);
    std::shared_ptr<LockCounter> counter = iterator->second;
    counter->Increase(remoteObj, lockInner);
    POWER_HILOGD(FEATURE_RUNNING_LOCK, "LockCounter type=%{public}d, count=%{public}d", lockInnerParam.type,
        counter->GetCount());
    if (timeOutMS > 0) {
        RemoveAndPostUnlockTask(remoteObj, timeOutMS);
    }
    FinishTrace(HITRACE_TAG_POWER);
}

int32_t RunningLockAction::Lock(const RunningLockParam& param)
{
    // 调用SystemSuspendController::AcquireRunningLock(...)
    return SystemSuspendController::GetInstance().AcquireRunningLock(param);
}

int32_t SystemSuspendController::AcquireRunningLock(const RunningLockParam& param)
{
    int32_t status = RUNNINGLOCK_FAILURE;
    if (powerInterface_ == nullptr) {
        POWER_HILOGE(COMP_SVC, "The hdf interface is null");
        return status;
    }
   
    // 根据不同的类型,调用不同的lock方法
    if (param.type == RunningLockType::RUNNINGLOCK_BACKGROUND) {
        // 写字符串到LOCK_PATH:"/sys/power/wake_lock"
        status = powerInterface_->SuspendBlock(param.name);
    } else {
        OHOS::HDI:ower::V1_1::RunningLockInfo filledInfo = FillRunningLockInfo(param);
        status = powerInterface_->HoldRunningLock(filledInfo);
    }
    return status;
}

int32_t PowerInterfaceImpl::SuspendBlock(const std::string &name)
{
    std::lock_guard<std::mutex> lock(g_mutex);
    if (name.empty()) {
        return HDF_ERR_INVALID_PARAM;
    }
    // static constexpr const char * const LOCK_PATH = "/sys/power/wake_lock";
    UniqueFd fd(TEMP_FAILURE_RETRY(open(LOCK_PATH, O_RDWR | O_CLOEXEC)));
    // 写字符串到LOCK_PATH
    bool ret = SaveStringToFd(fd, name);
    if (!ret) {
        return HDF_FAILURE;
    }
    return HDF_SUCCESS;
}

int32_t PowerInterfaceImpl::HoldRunningLock(const RunningLockInfo &info)
{
    return RunningLockImpl::Hold(info, g_powerState);
}


int32_t RunningLockImpl::Hold(const RunningLockInfo &info, PowerHdfState state)
{
    std::lock_guard<std::mutex> lock(mutex_);
    if (info.name.empty()) {
        HDF_LOGW("Runninglock hold failed, name is empty");
        return HDF_ERR_INVALID_PARAM;
    }
    RunningLockInfo filledInfo = FillRunningLockInfo(info);
    if (!IsValidType(filledInfo.type, state)) {
        HDF_LOGW("Runninglock hold failed, type=%{public}d or state=%{public}d is invalid", filledInfo.type, state);
        return HDF_ERR_INVALID_PARAM;
    }
   
    auto iterator = lockCounters_.find(filledInfo.type);
    // 若该类型未存在lockCounters_,将(locktype,RunningLockCounter)插入到lockCounters_
    if (iterator == lockCounters_.end()) {
        auto pair = lockCounters_.emplace(filledInfo.type,
            std::make_shared<RunningLockCounter>(filledInfo.type, GetRunningLockTag(filledInfo.type)));
        //emplace 失败则返回
        if (pair.second == false) {
            HDF_LOGW("Runninglock hold failed, type=%{public}d is not in lockCounters", filledInfo.type);
            return HDF_FAILURE;
        }
        // 成功,则赋值iterator
        iterator = pair.first;
    }
    std::shared_ptr<RunningLockCounter> lockCounter = iterator->second;
    // lockCounter计数增加
    if (lockCounter->Increase(filledInfo) != HDF_SUCCESS) {
        return HDF_FAILURE;
    }
    if (filledInfo.timeoutMs > 0) {
        if (timerHandler_ == nullptr) {
            timerHandler_ = std::make_unique<RunningLockTimerHandler>();
        }
        
        // timeoutMs > 0,则注册unhold函数, unhold与hold类似,不再展开介绍。
        std::function<void()> unholdFunc = std::bind(&RunningLockImpl::Unhold, filledInfo);
        timerHandler_->RegisterRunningLockTimer(filledInfo, unholdFunc);
    }
    return HDF_SUCCESS;
}

// once默认参数为true
bool RunningLockTimerHandler::RegisterRunningLockTimer(
    const RunningLockInfo &info, const std::function<void()> &callback, bool once)
{
    if (handlerTimer_ == nullptr) {
        handlerTimer_ = std::make_unique<OHOS::Utils::Timer>(RUNNINGLOCK_TIMER_HANDLER_NAME);
        handlerTimer_->Setup();
    }
    RunningLockType runninglockType = info.type;
    std::string runninglockName = info.name;
    uint32_t timeoutMs = info.timeoutMs;
    uint32_t lastTimerId = GetRunningLockTimerId(runninglockType, runninglockName);
    if (lastTimerId != OHOS::Utils::TIMER_ERR_DEAL_FAILED) {
        HDF_LOGI("Running lock timer is exist, unregister old timerId=%{public}d, register new timer", lastTimerId);
        UnregisterTimer(lastTimerId);
    }
    // 注册一个hold超时定时器
    uint32_t curTimerId = handlerTimer_->Register(callback, timeoutMs, once);
    if (curTimerId == OHOS::Utils::TIMER_ERR_DEAL_FAILED) {
        HDF_LOGW("Register running lock timer failed");
        if (lastTimerId != OHOS::Utils::TIMER_ERR_DEAL_FAILED) {
            RemoveRunningLockTimerMap(runninglockType, runninglockName);
        }
        return false;
    }
    // 增加或更新 RunningLockTimerMap的对应的元素
    AddRunningLockTimerMap(runninglockType, runninglockName, curTimerId);
    return true;
}

void RunningLockTimerHandler::AddRunningLockTimerMap(RunningLockType type, std::string name, uint32_t timerId)
{
    auto typeIter = runninglockTimerMap_.find(type);
    // 若runninglockTimerMap_没有,则新增
    if (typeIter == runninglockTimerMap_.end()) {
        std::map<std::string, uint32_t> timerIdMap;
        timerIdMap.emplace(name, timerId);
        runninglockTimerMap_.emplace(type, timerIdMap);
        return;
    }
   
    // 有则更新定时器
    auto nameIter = typeIter->second.find(name);
    if (nameIter == typeIter->second.end()) {
        typeIter->second.emplace(name, timerId);
        return;
    }
    nameIter->second = timerId;
}
```

### 手机近光传感器触发的亮灭屏流程

近光传感器的流程本文不涉及,只从调用PowerMgrClient接口开始,代码如下:

```c++
void ProximitySensor::StartUp(PowerMgr::WakeupDeviceType operationType, std::string wakeupReason)
{
    PowerMgr:owerMgrClient::GetInstance().WakeupDevice(operationType, wakeupReason);
}

PowerErrors PowerMgrClient::WakeupDevice(WakeupDeviceType reason, const std::string& detail)
{
    //查找POWER_MANAGER_SERVICE_ID,即上面注册的PowerMgrService服务
    //这里需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxStub-->xxService。
    RETURN_IF_WITH_RET(Connect() != ERR_OK, PowerErrors::ERR_CONNECTION_FAIL);
    POWER_HILOGD(FEATURE_WAKEUP, " Calling WakeupDevice success");
    return proxy_->WakeupDevice(GetTickCount(), reason, detail);
}
...
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)
{
    StartTrace(HITRACE_TAG_POWER, "WakeupDevice");
    if (type > WakeupDeviceType::WAKEUP_DEVICE_MAX) {
        POWER_HILOGW(FEATURE_WAKEUP, "Invalid type: %{public}d", type);
        return;
    }
    // Call legacy wakeup, Check the screen state
    if (stateAction_ != nullptr) {
        stateAction_->Wakeup(callTimeMs, type, details, pkgName);
    }
    mDeviceState_.lastWakeupDeviceTime = callTimeMs;

    // reset定时器并设置当前的状态为awake
    ResetInactiveTimer();
    SetState(PowerState::AWAKE, GetReasonByWakeType(type), true);

    FinishTrace(HITRACE_TAG_POWER);
    POWER_HILOGD(FEATURE_WAKEUP, "Wakeup device finish");
}

void DeviceStateAction::Wakeup(int64_t callTimeMs, WakeupDeviceType type, const string& details,
    const string& pkgName)
{
    // 调用 SystemSuspendController::Wakeup()
    SystemSuspendController::GetInstance().Wakeup();
}

void SystemSuspendController::Wakeup()
{
    if (powerInterface_ == nullptr) {
        POWER_HILOGE(COMP_SVC, "The hdf interface is null");
        return;
    }
    // 调用hdi的StopSuspend()
    powerInterface_->StopSuspend();
}

int32_t PowerInterfaceImpl::StopSuspend()
{
    g_suspendRetry = false;
    g_powerState = PowerHdfState::AWAKE;
    return HDF_SUCCESS;
}

-----------------------------------------------------------------
//该函数在StartSuspend()方法时,会开启一个daemon线程与其bind
void AutoSuspendLoop()
{
    auto suspendLock = std::unique_lock(g_suspendMutex);
    while (true) {
        std::this_thread::sleep_for(waitTime_);

        const std::string wakeupCount = ReadWakeCount();
        if (wakeupCount.empty()) {
            continue;
        }
        // 此处检测g_suspendRetry,若为false,则会在此等待g_suspendCv,即不会继续后面的Suspend
        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;
}
---------------------------------------- ---------------------
```

### 发布公共事件的流程

电源管理服务只是实现了公共事件的部分流程,相关代码如下:

```c++
// 该方法,未见有调用之处
void PowerStateMachine::ReceiveScreenEvent(bool isScreenOn)
{
    POWER_HILOGD(FEATURE_POWER_STATE, "Enter");
    std::lock_guard lock(mutex_);
    auto prestate = mDeviceState_.screenState.state;
    if (isScreenOn) {
        mDeviceState_.screenState.lastOnTime = GetTickCount();
    } else {
        mDeviceState_.screenState.lastOffTime = GetTickCount();
    }
    if (prestate != mDeviceState_.screenState.state) {
        NotifyPowerStateChanged(isScreenOn ? PowerState::AWAKE : PowerState::INACTIVE);
    }
}

// PowerStateMachine::StateController::TransitTo中,屏幕状态转换成功后,会调用NotifyPowerStateChanged
void PowerStateMachine::NotifyPowerStateChanged(PowerState state)
{
    POWER_HILOGI(
        FEATURE_POWER_STATE, "state = %{public}u, listeners.size = %{public}zu", state, powerStateListeners_.size());
    HiSysEventWrite(HiviewDFX::HiSysEvent:omain:OWER, "STATE", HiviewDFX::HiSysEvent::EventType::STATISTIC, "STATE",
        static_cast<uint32_t>(state));
    std::lock_guard lock(mutex_);
    int64_t now = GetTickCount();
    // Send Notification event
    SendEventToPowerMgrNotify(state, now);

    // Call back all native function
    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(FEATURE_POWER_STATE, "Pms is nullptr");
        return;
    }
    auto notify = pms->GetPowerMgrNotify();
    if (notify == nullptr) {
        POWER_HILOGE(FEATURE_POWER_STATE, "Notify is null");
        return;
    }
    if (state == PowerState::AWAKE) {
        notify->PublishScreenOnEvents(callTime);
    } else if (state == PowerState::INACTIVE) {
        notify->PublishScreenOffEvents(callTime);
    } else {
        POWER_HILOGI(FEATURE_POWER_STATE, "No need to publish event, state:%{public}u", state);
    }
}

void PowerMgrNotify:ublishScreenOffEvents(int64_t eventTime)
{
    POWER_HILOGI(FEATURE_SUSPEND, "Start to publish event %{public}s at %{public}lld",
        screenOffWant_->GetAction().c_str(), static_cast<long long>(eventTime));
    PublishEvents(eventTime, screenOffWant_);
    POWER_HILOGI(FEATURE_SUSPEND, "Publish event %{public}s done", screenOffWant_->GetAction().c_str());
}

void PowerMgrNotify:ublishScreenOnEvents(int64_t eventTime)
{
    POWER_HILOGI(FEATURE_WAKEUP, "Start to publish event %{public}s at %{public}lld",
        screenOnWant_->GetAction().c_str(), static_cast<long long>(eventTime));
    PublishEvents(eventTime, screenOnWant_);
    POWER_HILOGI(FEATURE_WAKEUP, "Publish event %{public}s done", screenOnWant_->GetAction().c_str());
}

//发送COMMON_EVENT_SCREEN_ON/COMMON_EVENT_SCREEN_OFF公共事件
void PowerMgrNotify::PublishEvents(int64_t eventTime, sptr<IntentWant> want)
{
    if ((want == nullptr) || (publishInfo_ == nullptr)) {
        POWER_HILOGE(COMP_SVC, "Invalid parameter");
        return;
    }
    CommonEventData event(*want);
    // ./base/notification/common_event_service/interfaces/inner_api/common_event_manager.h
    // 调用static方法:CommonEventManager::PublishCommonEvent
    CommonEventManager::PublishCommonEvent(event, *publishInfo_, nullptr);
}

// 初始化时,会掉调用该函数,供后续的PublishScreenOnEvents调用
void PowerMgrNotify::RegisterPublishEvents()
{
    if (publishInfo_ != nullptr) {
        return;
    }
    publishInfo_ = new (std::nothrow)CommonEventPublishInfo();
    publishInfo_->SetOrdered(false);
    screenOffWant_ = new (std::nothrow)IntentWant();
    screenOffWant_->SetAction(CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
    screenOnWant_ = new (std::nothrow)IntentWant();
    screenOnWant_->SetAction(CommonEventSupport::COMMON_EVENT_SCREEN_ON);
}
```

## 总结

本文主要和大家分享了OpenHarmony电源管理子系统的实现,重点分析了电池服务组件、显示控制组件和电源管理服务组件的服务注册、启动,以及典型的接口调用流程,做了较为详细的代码说明,希望通过本文您能初步掌握电源管理子系统的关键功能和核心流程。关于OpenHarmony其它子系统的分析,请关注后续文章。



[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5