OpenHarmony-5.PM 子系统(2)

  • 电池服务组件
  • OpenHarmony-4.1-Release

1.电池服务组件

  Battery Manager 提供了电池信息查询的接口,同时开发者也可以通过公共事件监听电池状态和充放电状态的变化。电池服务组件提供如下功能:

  • 电池信息查询。
  • 充放电状态查询。
  • 关机充电。

  电池服务组件架构图:
在这里插入图片描述

1.1.代码目录:

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                       # 工具和通用层
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                       # 工具和通用层

1.2.电池和充电属性接口

  该模块主要提供电池状态和充放电状态的查询接口。batteryInfo类用来描述电池信息。

  • powermgr_battery_manager\interfaces\inner_api\native\include\battery_info.h

在这里插入图片描述
在这里插入图片描述
1.3.Battery Service 服务启动

  Battery Service 服务被打包到 foundation 进程。System Ability 管理模块用于管理系统基础能力,本服务需要向该模块注册,如果没有编写 profile 配置,则 System Ability 管理模块在启动时不会注册该服务。

powermgr_battery_manager\sa_profile\3302.json
注册信息:
  1 {
  2     "process": "foundation",
  3     "systemability": [
  4         {
  5             "name": 3302,
  6             "libpath": "libbatteryservice.z.so",
  7             "run-on-create": true,
  8             "distributed": false,
  9             "dump_level": 1
 10         }
 11     ]
 12 }
  • name:为对应的serviceId必须与代码中注册的serviceId保持一致;电池服务组件的serviceId为3302;
  • libpath:为SystemAbility的加载路径,必配项;
  • run-on-create:true表示进程启动后即向samgr组件注册该SystemAbility;false表示按需启动,即在其他模块访问到该SystemAbility时启动;必配项;
  • distributed:true表示该SystemAbility为分布式SystemAbility,支持跨设备访问;false表示只有本地跨IPC访问;
  • dump-level:表示systemdumper支持的level等级,默认配置1就OK;
  • 注册信息配置文件:/system/profile/foundation.xml

1.3.1.注册代码

powermgr_battery_manager\services\native\src\battery_service.cpp
//调用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 的启动函数实现电池服务组件的启动:

powermgr_battery_manager\services\native\src\battery_service.cpp
void BatteryService::OnStart()
{
    //如果已启动则返回(BatteryService是单实例服务,只会启动一个)
    if (ready_) {
        BATTERY_HILOGD(COMP_SVC, "Service is ready, nothing to do");
        return;
    }
    //创建BatterysrvEventHandler实例
    //等待CommonEventService服务启动完成之后初始化完成
    if (!(Init())) {         //调用BatteryService::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;
}

  重点分析:

  • BatteryService::Init
bool BatteryService::Init()
{
    InitConfig();        //解析battery_config.json
    if (!batteryNotify_) {
        batteryNotify_ = std::make_unique<BatteryNotify>();
    }
    VibratorInit();     //解析battery_vibrator.json
    RegisterBootCompletedCallback();
    return true;
}
  • RegisterHdiStatusListener();
 ->RegisterBatteryHdiCallback();
   ->ErrCode ret = iBatteryInterface_->Register(callback); 
        //drivers_peripheral\battery\interfaces\hdi_service\src\battery_interface_impl.cpp
   		(即 BatteryInterfaceImpl::Register(const sptr<IBatteryCallback>& callback)) 

1.3.2.BatteryInterfaceDriver 启动

  BatteryInterfaceDriver 是 HDI(即驱动接口)层服务,打包在 power_host 进程。本文主要分析 batteryd 的实现。

  device_info.hcs 节点配置:

/vendor/hihope/rk3568/hdf_config/uhdf/device_info.hcs
140         power :: host {
141             hostName = "power_host";
142             priority = 50;
143             uid = "power_host";
144             gid = ["power_host", "system", "log"];
145             caps = ["BLOCK_SUSPEND"];
146             power_device :: device {
147                 device0 :: deviceNode {
148                     policy = 2;
149                     priority = 100;
150                     moduleName = "libpower_driver.z.so";
151                     serviceName = "power_interface_service";
152                 }
153             }
154             battery_device :: device {
155                 device0 :: deviceNode {
156                     policy = 2;
157                     priority = 100;
158                     moduleName = "libbattery_driver.z.so";
159                     serviceName = "battery_interface_service";
160                 }
161             }
162             thermal_device :: device {
163                 device0 :: deviceNode {
164                     policy = 2;
165                     priority = 100;
166                     moduleName = "libthermal_driver.z.so";
167                     serviceName = "thermal_interface_service";
168                 }
169             }
170         }

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

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

  batteryd 驱动程序初始化接口:

drivers_peripheral\battery\interfaces\hdi_service\src\battery_interface_driver.cpp
static struct HdfDriverEntry g_batteryInterfaceDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "battery_interface_service",
    .Bind = HdfBatteryInterfaceDriverBind,
    .Init = HdfBatteryInterfaceDriverInit,
    .Release = HdfBatteryInterfaceDriverRelease,
};


static int32_t HdfBatteryInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
{
    auto *hdfBatteryInterfaceHost = new (std::nothrow) HdfBatteryInterfaceHost;

    //绑定BatteryInterfaceDriverDispatch作为消息处理函数。
    hdfBatteryInterfaceHost->ioService.Dispatch = BatteryInterfaceDriverDispatch;
    hdfBatteryInterfaceHost->ioService.Open = nullptr;
    hdfBatteryInterfaceHost->ioService.Release = nullptr;

    auto serviceImpl = IBatteryInterface::Get(true);

    hdfBatteryInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
        IBatteryInterface::GetDescriptor());

    //IO Service 完成 IPC 通信的客户端消息请求封装,IO Dispatcher 完成驱动服务端消息请求封装
    //客户端消息通过 IPC 通信到达服务端并分发给 IO Dispatcher 处理。
    deviceObject->service = &hdfBatteryInterfaceHost->ioService;
    return HDF_SUCCESS;
}

  BatteryInterfaceImpl接口:

  通过调用BatteryInterfaceImplGetInstance接口实例BatteryInterfaceImpl对象,并且调用调用BatteryInterfaceImpl::Init进行初始化。

  • 初始化电池信息路径;
  • 调用调用BatteryThread::StartThread.
drivers_peripheral\battery\interfaces\hdi_service\src\battery_interface_impl.cpp
extern "C" IBatteryInterface *BatteryInterfaceImplGetInstance(void)
{
    using OHOS::HDI::Battery::V2_0::BatteryInterfaceImpl;
    BatteryInterfaceImpl *service = new (std::nothrow) BatteryInterfaceImpl();

    if (service->Init() != HDF_SUCCESS) {  //调用BatteryInterfaceImpl::Init
        delete service;
        return nullptr;
    }

    return service;
}

int32_t BatteryInterfaceImpl::Init()
{
    powerSupplyProvider_ = std::make_unique<OHOS::HDI::Battery::V2_0::PowerSupplyProvider>();

    powerSupplyProvider_->InitBatteryPath();
    powerSupplyProvider_->InitPowerSupplySysfs();

    auto& batteryConfig = BatteryConfig::GetInstance();

    batteryConfig.ParseConfig();

    loop_ = std::make_unique<OHOS::HDI::Battery::V2_0::BatteryThread>();

    if (batteryCallback_ != nullptr) {
        loop_->InitCallback(batteryCallback_);
    } else {
        BATTERY_HILOGW(COMP_HDI, "batteryCallback_ is nullptr");
    }
    loop_->StartThread(this);  //调用BatteryThread::StartThread

    return HDF_SUCCESS;
}

drivers_peripheral\battery\interfaces\hdi_service\src\battery_thread.cpp
//在BatteryInterfaceImpl::Init() 启动初始化阶段启动本线程,用于处理kernel发来的消息
void BatteryThread::StartThread(void* service)
{
    Init(service);
    Run(service);
}

1.3.3.电池 batteryInfo 信息查询流程

  采用NAPI (Native API)获取电池信息,NAPI 组件是一套对外接口基于Node.js N-API规范开发的原生模块扩展开发框架。NAPI组件架构图:

在这里插入图片描述
  NAPI适合封装IO、CPU密集型、OS底层等能力并对外暴露JS接口,通过NAPI可以实现JS与C/C++代码互相访问。我们可以通过NAPI接口构建例如网络通信、串口访问、多媒体解码、传感器数据收集等模块。接口实现详见:foundation/arkui/napi。

powermgr_battery_manager\frameworks\napi\battery_info.cpp:
static napi_module g_module = {.nm_version = 1,
    .nm_flags = 0,
    .nm_filename = "batteryInfo",
    .nm_register_func = BatteryInit,
    .nm_modname = "batteryInfo",
    .nm_priv = ((void*)0),
    .reserved = {0}};

extern "C" __attribute__((constructor)) void RegisterModule(void)
{
    napi_module_register(&g_module);
}
  • BatteryInit
static napi_value BatteryInit(napi_env env, napi_value exports)
{
    BATTERY_HILOGD(COMP_FWK, "Enter");

    napi_property_descriptor desc[] = {
        DECLARE_NAPI_GETTER("batterySOC", BatterySOC),
        DECLARE_NAPI_GETTER("chargingStatus", GetChargingState),
        DECLARE_NAPI_GETTER("healthStatus", GetHealthState),
        DECLARE_NAPI_GETTER("pluggedType", GetPluggedType),
        DECLARE_NAPI_GETTER("voltage", GetVoltage),
        DECLARE_NAPI_GETTER("technology", GetTechnology),
        DECLARE_NAPI_GETTER("batteryTemperature", GetBatteryTemperature),
        DECLARE_NAPI_GETTER("isBatteryPresent", GetBatteryPresent),
        DECLARE_NAPI_GETTER("batteryCapacityLevel", GetCapacityLevel),
        DECLARE_NAPI_GETTER("estimatedRemainingChargeTime", GetRemainingChargeTime),
        DECLARE_NAPI_GETTER("nowCurrent", GetBatteryNowCurrent),
        DECLARE_NAPI_GETTER("remainingEnergy", GetBatteryRemainEnergy),
        DECLARE_NAPI_GETTER("totalEnergy", GetTotalEnergy),
        DECLARE_NAPI_FUNCTION("setBatteryConfig", SetBatteryConfig),
        DECLARE_NAPI_FUNCTION("getBatteryConfig", GetBatteryConfig),
        DECLARE_NAPI_FUNCTION("isBatteryConfigSupported", IsBatteryConfigSupported),
    };
    NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));

    CreateEnumPluggedType(env, exports);
    CreateEnumChargeState(env, exports);
    CreateEnumHealthState(env, exports);
    CreateEnumLevelState(env, exports);
    CreateEventBatteryChangedKey(env, exports);
    CreateEventBatteryChangedCode(env, exports);

    BATTERY_HILOGD(COMP_FWK, "Success");

    return exports;
}

  应用调用接口获取当前设备剩余电池容量(batterySOC)为例:

applications/standard/app_samples/code/SystemFeature/DeviceManagement/DeviceManagementCollection/feature/capabilities/src/main/ets/util/
//导入模块
import batteryInfo from '@ohos.batteryInfo';

60   /**
61    * 获取当前设备剩余电池电量百分比
62    */
63   public getBatterySOC(): string {
64     let soc: number = this.disposeBatterySOC(batteryInfo.batterySOC)   //调用batterySOC查询接口
65     logger.info(`${this.TAG} getChargingStatus: ${soc}`)
66     return soc.toString()
67   }
68 

  NAPI 接口实现BatterySOC,BatterySOC调用流程:

g_battClient.GetCapacity()->BatterySrvClient::GetCapacity()
   ->BatteryService::GetCapacity()
   	 ->BatteryInterface::GetCapacity(capacity)
   	 	-> PowerSupplyProvider::ParseCapacity
   	 	   ->PowerSupplyProvider::ReadBatterySysfsToBuff
   	 	   	 ->open

  详细分析:

powermgr_battery_manager\frameworks\napi\battery_info.cpp
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;
}

powermgr_battery_manager\frameworks\native\src\battery_srv_client.cpp
int32_t BatterySrvClient::GetCapacity()
{
    auto proxy = Connect();
    
    //查找到到POWER_MANAGER_BATT_SERVICE_ID(即BatteryService)服务并赋值给proxy_
    //需要了解SystemAbility IPC机制,xxClient-->xxProxy-->xxStub-->xxService。
    RETURN_IF_WITH_RET(proxy == nullptr, INVALID_BATT_INT_VALUE);
    //调用BatteryService::GetCapacity()
    return proxy->GetCapacity();
}

powermgr_battery_manager\services\native\src\battery_service.cpp
int32_t BatteryService::GetCapacity()
{
    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;
}

drivers_peripheral\battery\interfaces\hdi_service\src\battery_interface_impl.cpp
// BatteryInterfaceImpl 实现IBatteryInterface的纯虚函数
int32_t BatteryInterfaceImpl::GetCapacity(int32_t& capacity)
{
   // 调用 PowerSupplyProvider::ParseCapacity(...)
    return powerSupplyProvider_->ParseCapacity(&capacity);
}

drivers_peripheral\battery\interfaces\hdi_service\src\power_supply_provider.cpp
int32_t PowerSupplyProvider::ParseCapacity(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);
    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);

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

    return HDF_SUCCESS;
}

1.3.4.电池 batteryinfo 信息变更发布流程

  BatteryThread接口:

drivers_peripheral\battery\interfaces\hdi_service\src\battery_thread.cpp
int32_t BatteryThread::Init([[maybe_unused]] void* service)
{
    provider_ = std::make_unique<PowerSupplyProvider>();
    if (provider_ != nullptr) {
        provider_->InitBatteryPath();
        provider_->InitPowerSupplySysfs();
    }
    epFd_ = epoll_create1(EPOLL_CLOEXEC);  //创建epoll 实例,用于异步事件通知
    InitUevent();      //初始化uevent, 并且注册回调函数UeventCallback
    return HDF_SUCCESS;
}

void BatteryThread::Run(void* service)
{
    batteryThread_ = std::make_unique<std::thread>([this, service] { this->LoopingThreadEntry(service); });
    pthread_setname_np(batteryThread_->native_handle(), "battery_thread");
}

void BatteryThread::LoopingThreadEntry(void* arg)
{
    int32_t nevents = 0;
    size_t size = callbacks_.size();
    struct epoll_event events[size];

    while (isRunning_) {
        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';
    std::string powerUevent;
    if (!MatchPowerUevent(msg, powerUevent)) {
        return;
    }
    BATTERY_HILOGD(FEATURE_BATT_INFO, "PowerUevent msg:%{public}s", powerUevent.c_str());
    UpdateBatteryInfo(service, powerUevent);
}

//更新电池信息
void BatteryThread::UpdateBatteryInfo(void* service, const std::string& powerUevent)
{
    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_;
    event.uevent = powerUevent;

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

  framework service端接口:

powermgr_battery_manager\services\native\src\battery_service.cpp
bool BatteryService::RegisterBatteryHdiCallback()
{
    std::lock_guard<std::shared_mutex> lock(mutex_);
    if (iBatteryInterface_ == nullptr) {
        iBatteryInterface_ = V2_0::IBatteryInterface::Get();
        BATTERY_HILOGE(COMP_SVC, "failed to get battery hdi interface");
        RETURN_IF_WITH_RET(iBatteryInterface_ == nullptr, false);
    }
    // 向BatteryInterface 注册一个 BatteryCallback,
    sptr<V2_0::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;
}


int32_t BatteryService::HandleBatteryCallbackEvent(const V2_0::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()
{
    batteryLight_.UpdateColor(batteryInfo_.GetChargeState(), batteryInfo_.GetCapacity());
    // 若有外接电源插入/拔出,则唤醒设备
    WakeupDevice(batteryInfo_.GetPluggedType());
     // 根据batteryInfo_,更新 
    CalculateRemainingChargeTime(batteryInfo_.GetCapacity(), batteryInfo_.GetChargeState());
    // BatteryNotify 发布电池信息更新事件
    batteryNotify_->PublishEvents(batteryInfo_);
    //其他信息更新
    HandleTemperature(batteryInfo_.GetTemperature());
    HandleCapacity(batteryInfo_.GetCapacity(), batteryInfo_.GetChargeState());
    lastBatteryInfo_ = batteryInfo_;
}

2.电量等级定制开发

 &加粗样式ensp;OpenHarmony默认提供了电量等级,根据当前的电量来定义系统统一的电量等级,如满电量、高电量、低电量、极低电量等。系统可以根据当前的电量等级对用户进行提示或处理相关业务。但是电量等级对应的电量值在不同的产品上规格是不同的,产品希望根据产品的设计规格来定制此特性。为此OpenHarmony提供了电量等级的定制方式,产品定制开发者可根据设计规格来定制此特性。battery_config.cpp(drivers_peripheral\battery\interfaces\hdi_service\src\)解析配置文件battery_config.json。

drivers/peripheral/battery/interfaces/hdi_service/profile/battery_config.json:
1 {
2     "light": {
3         "low": {
4             "soc": [0, 10],
5             "rgb": [255, 0, 0]
6         },
7         "normal": {
8             "soc": [10, 90],
9             "rgb": [255, 255, 0]
10         },
11         "high": {
12             "soc": [90, 100],
13             "rgb": [0, 255, 0]
14         }
15     },
16     "boot_actions": {
17         "sendcommonevent": [{
18             "event_name": "usual.event.BATTERY_CHANGED",
19             "scene_config": {
20                 "name" : "wireless",
21                 "not_equal" : "0"
22             },
23             "uevent": "battery common event"
24         }]
25     },
26     "temperature": {
27         "high": 680,
28         "low": -500
29     },
30     "soc": {
31         "shutdown": 5,
32         "critical": 10,
33         "warning": 15,
34         "low": 30,
35         "normal": 60,
36         "high": 90,
37         "full": 100
38     },
39     "charger": {
40         "current_limit":{
41             "path": "/data/service/el0/battery/current_limit"
42         },
43         "voltage_limit":{
44             "path": "/data/service/el0/battery/voltage_limit"
45         },
46         "type": {
47             "path": "/data/service/el0/battery/charger_type"
48         }
49     }
50 }

  电量等级配置说明:
在这里插入图片描述

refer to

  • https://gitee.com/openharmony/powermgr_battery_manager
  • https://gitee.com/openharmony/ace_napi/tree/master
  • https://forums.openharmony.cn/forum.php?mod=viewthread&tid=616
  • http://test.openharmony.cn:7780/pages/v4.1/zh-cn/device-dev/subsystems/subsys-power-battery-level-customization.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/944431.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 网络原理 ①-IO多路复用 || 自定义协议 || XML || JSON

这里是Themberfue 在学习完简单的网络编程后&#xff0c;我们将更加深入网络的学习——HTTP协议、TCP协议、UDP协议、IP协议........... IO多路复用 ✨在上一节基于 TCP 协议 编写应用层代码时&#xff0c;我们通过一个线程处理连接的申请&#xff0c;随后通过多线程或者线程…

基于规则的系统架构:理论与实践

在当今信息化快速发展的时代&#xff0c;企业面临着日益复杂和多变的市场环境&#xff0c;传统的静态系统架构已难以满足快速响应业务变化的需求。基于规则的系统架构&#xff08;Rule-Based System Architecture, RBSA&#xff09;作为一种灵活、可扩展的架构模式&#xff0c;…

记一个itertools排列组合和列表随机排序的例子

朋友不知道哪里弄来了一长串单词列表&#xff0c;一定要搞个单词不重复的组合。那么这个时候我们就可以想到读书时所学的排列组合知识了&#xff0c;而这个在Python中可以怎么实现呢&#xff1f;我记录如下&#xff1a; 使用itertools模块实现排列组合 在 Python 中&#xff…

从0入门自主空中机器人-4-【PX4与Gazebo入门】

前言: 从上一篇的文章 从0入门自主空中机器人-3-【环境与常用软件安装】 | MGodmonkeyの世界 中我们的机载电脑已经安装了系统和常用的软件&#xff0c;这一篇文章中我们入门一下无人机常用的开源飞控PX4&#xff0c;以及ROS中无人机的仿真 1. PX4的安装 1.1 PX4固件代码的下载…

搭建vue项目

一、环境准备 1、安装node node官网&#xff1a;https://nodejs.org/zh-cn 1.1、打开官网&#xff0c;选择“下载”。 1.2、选择版本号&#xff0c;选择系统&#xff0c;根据需要自行选择&#xff0c;上面是命令安装方式&#xff0c;下载是下载安装包。 1.3、检查node安装…

深度学习笔记(5)——目标检测和图像分割

目标检测与图像分割 语义分割:如果没有语义信息,很难正确分类每个像素 解决方案:感知像素周围的语义,帮助正确分类像素 滑窗计算:计算非常低效,图像块的重叠部分会被重复计算很多次 解决方案:转向全卷积 全卷积问题:分类模型会大幅降低特征的分辨率,难以满足分割所需的高分辨…

go语言的成神之路-筑基篇-gin常用功能

第一节-gin参数绑定 目录 第一节-?gin参数绑定 ShouldBind简要概述 功能&#xff1a; 使用场景&#xff1a; 可能的错误&#xff1a; 实例代码 效果展示 第二节-gin文件上传 选择要上传的文件 选择要上传的文件。 效果展示? 代码部分 第三节-gin请求重定向 第…

【Leecode】Leecode刷题之路第93天之复原IP地址

题目出处 93-复原IP地址-题目描述 题目描述 个人解法 思路&#xff1a; todo代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo官方解法 93-复原IP地址-官方解法 方法1&#xff1a;回溯 思路&#xff1a; 代码示例&#xff1a;&#xff08;Java&…

【新方法】通过清华镜像源加速 PyTorch GPU 2.5安装及 CUDA 版本选择指南

下面详细介绍所提到的两条命令&#xff0c;它们的作用及如何在你的 Python 环境中加速 PyTorch 等库的安装。 1. 设置清华镜像源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple这条命令的作用是将 pip &#xff08;Python 的包管理工具&#xf…

CES Asia 2025的低空经济展区有哪些亮点?

CES Asia 2025&#xff08;赛逸展&#xff09;的低空经济展区有以下亮点&#xff1a; • 前沿科技产品展示&#xff1a; 多款新型无人机将亮相&#xff0c;如固定翼无人机和系留无人机的最新型号&#xff0c;其在监测、救援和货物运输等方面功能强大。此外&#xff0c;还有可能…

python数据分析之爬虫基础:selenium详细讲解

目录 1、selenium介绍 2、selenium的作用&#xff1a; 3、配置浏览器驱动环境及selenium安装 4、selenium基本语法 4.1、selenium元素的定位 4.2、selenium元素的信息 4.3、selenium元素的交互 5、Phantomjs介绍 6、chrome handless模式 1、selenium介绍 &#xff08;1…

Python学生管理系统(MySQL)

上篇文章介绍的Python学生管理系统GUI有不少同学觉得不错来找博主要源码&#xff0c;也有同学提到老师要增加数据库管理数据的功能&#xff0c;本篇文章就来介绍下python操作数据库&#xff0c;同时也对上次分享的学生管理系统进行了改进了&#xff0c;增加了数据库&#xff0c…

二,Python常用库(共16个)

二&#xff0c;常用库(共15个 二&#xff0c;Python常用库(共15个)1&#xff0c;os模块2&#xff0c;json模块2.1 猴子补丁S 3&#xff0c;random模块4&#xff0c;string模块5&#xff0c;异常处理5.1 错误类型5.1 逻辑错误两种处理方式5.1.1 错误时可以预知的5.1.2 错误时不可…

Linux第99步_Linux之点亮LCD

主要学习如何在Linux开发板点亮屏&#xff0c;以及modetest命令的实现。 很多人踩坑&#xff0c;我也是一样。关键是踩坑后还是实现不了&#xff0c;这样的人确实很多&#xff0c;从群里可以知道。也许其他人没有遇到这个问题&#xff0c;我想是他运气好。 1、修改设备树 1)、…

解密MQTT协议:从QOS到消息传递的全方位解析

1、QoS介绍 1.1、QoS简介 使用MQTT协议的设备大部分都是运行在网络受限的环境下&#xff0c;而只依靠底层的TCP传输协议&#xff0c;并不 能完全保证消息的可靠到达。 MQTT提供了QoS机制&#xff0c;其核心是设计了多种消息交互机制来提供不同的服务质量&#xff0c;来满足…

网络安全 | 5G网络安全:未来无线通信的风险与对策

网络安全 | 5G网络安全&#xff1a;未来无线通信的风险与对策 一、前言二、5G 网络的技术特点2.1 超高速率与低延迟2.2 大容量连接与网络切片 三、5G 网络面临的安全风险3.1 网络架构安全风险3.2 设备终端安全风险3.3 应用场景安全风险3.4 用户隐私安全风险 四、5G 网络安全对策…

MyBatis知识点笔记

目录 mybatis mapper-locations的作用&#xff1f; mybatis configuration log-impl 作用&#xff1f; resultType和resultMap的区别&#xff1f; 参数 useGeneratedKeys &#xff0c;keyColumn&#xff0c;keyProperty作用和用法 取值方式#和$区别 动态标签有哪些 MyBat…

Midjourney技术浅析(二):文本预处理过程

Midjourney 的用户通过输入文本描述&#xff08;Prompts&#xff09;来生成高质量的图像。为了将用户输入的文本转化为机器可理解的格式&#xff0c;并提取其中的语义信息&#xff0c;Midjourney 依赖于强大的自然语言处理&#xff08;NLP&#xff09;预处理技术。 一、NLP 预…

考研互学互助系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库…

ASP.NET Core Web API Hangfire

ASP.NET Core Web API Hangfire 前言一、安装二、相关代码1.代码片段2.代码片段3.运行效果 三、测试代码1.即发即弃作业2.延迟作业3.重复作业4.延续作业5.页面调度作业 前言 &#x1f468;‍&#x1f4bb;&#x1f468;‍&#x1f33e;&#x1f4dd;记录学习成果&#xff0c;以…