Android Healthd BartteryMonitor

目录

Android PowerSupply (一)总概

Android PowerSupply (二)power_supply_core

Android PowerSupply (三)power_supply_sys

Android PowerSupply (四)ChargeIC SGM41511 IC driver调试

Android PowerSupply (五)ChargeIC SGM41511 IC简介

Android Healthd BartteryMonitor

Healthd

health@1.0android.hardware.health@1.0 的缩写,指的是 Android 8.0 中发布的运行状况 HIDL 的 1.0 版 HAL。

health@2.0android.hardware.health@2.0 的缩写,指的是 Android 9 中发布的运行状况 HIDL 的 2.0 版 HAL。

AndroidP 引入了从 health@1.0 HAL 升级的主要版本 android.hardware.health HAL 2.0。新版 HAL 具有以下优势:

  • 框架代码和供应商代码之间的区别更清楚。
  • 弃用了不必要的 healthd 守护进程。
  • 供应商对运行状况信息报告进行自定义的自由度更高。
  • 更多设备运行状况信息(不仅包括电池信息)。

代码路径:android9/code/system/core/healthd

代码结构:

:~/prj/android9/code/system/core/healthd$ tree -l
.
├── Android.bp
├── android.hardware.health@2.0-service.rc
├── Android.mk
├── animation.h
├── AnimationParser.cpp
├── AnimationParser.h
├── BatteryMonitor.cpp
├── charger.cpp
├── charger_test.cpp
├── healthd_draw.cpp
├── healthd_draw.h
├── healthd_mode_charger.cpp
├── healthd.rc
├── HealthServiceDefault.cpp
├── HealthServiceHealthd.cpp
├── images
│   ├── battery_fail.png
│   └── battery_scale.png
├── include
│   └── healthd
│       ├── BatteryMonitor.h
│       └── healthd.h
├── OWNERS
└── tests
    ├── Android.mk
    └── AnimationParser_test.cpp

在Android9 中运行的情况

该框架尝试从 hwservicemanager 中检索 health@2.0 服务。如果检索失败,它将调用 health@1.0(在 Android 8.x 中提供)。同时,它还会保留原有代码路径,以便 Android 9 系统映像与 Android 8.x 供应商映像兼容。框架不会同时从两个 HAL 中检索信息,因为设备上只能存在一个服务版本(1.0 或 2.0)。

注意:对于原有代码路径,进程/库将一直保留到 health@1.0 被弃用

对于其他模式:

BartteryMonitor Class类


BatteryMonitor类

class BatteryMonitor {
  public:
    enum PowerSupplyType {
        ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0,
        ANDROID_POWER_SUPPLY_TYPE_AC,
        ANDROID_POWER_SUPPLY_TYPE_USB,
        ANDROID_POWER_SUPPLY_TYPE_WIRELESS,
        ANDROID_POWER_SUPPLY_TYPE_BATTERY
    };
//!< Battery关注点在系统供电上,获取power supply的类型分别有 AC, usb, wireless battery 4种类型 By: jixuan 2021年6月10日
    BatteryMonitor();
    void init(struct healthd_config *hc); //!< 初始化 
    bool update(void); //!< Battery信息的更新
    int getChargeStatus(); //!< 充电状态获取 
    status_t getProperty(int id, struct BatteryProperty *val);
    void dumpState(int fd);
    friend struct BatteryProperties getBatteryProperties(BatteryMonitor* batteryMonitor);

  private:
    struct healthd_config *mHealthdConfig;
    Vector<String8> mChargerNames;
    bool mBatteryDevicePresent;
    int mBatteryFixedCapacity;
    int mBatteryFixedTemperature;
    struct BatteryProperties props;

    int getBatteryStatus(const char* status);
    int getBatteryHealth(const char* status);
    int readFromFile(const String8& path, std::string* buf);
    PowerSupplyType readPowerSupplyType(const String8& path);
    bool getBooleanField(const String8& path);
    int getIntField(const String8& path);
};

 init函数

void BatteryMonitor::init(struct healthd_config *hc) {
    String8 path;
    char pval[PROPERTY_VALUE_MAX];

    mHealthdConfig = hc;
    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
	 //!< unique_ptr C++11 智能指针的一种,用于内存管理 
	 //!< decltype  为了解决复杂的类型声明 是decltype类型说明符关键字 
    if (dir == NULL) { //!< 打开powersupply目录,默认sys/class/power_supply 
        KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
    } else {
        struct dirent* entry;
        while ((entry = readdir(dir.get()))) {  //!< 获取powersupply下每一个目录名 
            const char* name = entry->d_name;
            path.clear();
            path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
            switch(readPowerSupplyType(path)) { //!< 判断powersupply类型 
            case ANDROID_POWER_SUPPLY_TYPE_AC: 
            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
                path.clear();
                path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
                if (access(path.string(), R_OK) == 0)
                    mChargerNames.add(String8(name));
				//!< 添加一个charge类型      powersupply 基础属性online 
                break;

            case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
                mBatteryDevicePresent = true;
				 //!< 找到battery powersupply存在 
			     //!< 逐个判断battery下存在的属性 
                if (mHealthdConfig->batteryStatusPath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
                                      name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryStatusPath = path;
                } //!< 查找status 若存在配置路径 
                if (mHealthdConfig->batteryHealthPath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
                                      name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryHealthPath = path;
                } //!< 查找Health 若存在配置路径 
                if (mHealthdConfig->batteryPresentPath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
                                      name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryPresentPath = path;
                } //!< 查找Present 若存在配置路径 

                if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
                                      name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryCapacityPath = path;
                } //!< 查找Capacity 若存在配置路径 

                if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/voltage_now",
                                      POWER_SUPPLY_SYSFS_PATH, name);
                    if (access(path, R_OK) == 0) {
                        mHealthdConfig->batteryVoltagePath = path;
                    }
                }  //!< 查找voltage_now 若存在配置路径 

                if (mHealthdConfig->batteryFullChargePath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/charge_full",
                                      POWER_SUPPLY_SYSFS_PATH, name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryFullChargePath = path;
                } //!< 查找charge_full 若存在配置路径

                if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/current_now",
                                      POWER_SUPPLY_SYSFS_PATH, name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryCurrentNowPath = path;
                } //!< 查找current_now 若存在配置路径 

                if (mHealthdConfig->batteryCycleCountPath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/cycle_count",
                                      POWER_SUPPLY_SYSFS_PATH, name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryCycleCountPath = path;
                }//!< 查找cycle_count 若存在配置路径 
                if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/current_avg",
                                      POWER_SUPPLY_SYSFS_PATH, name);
                    if (access(path, R_OK) == 0)
                        mHealthdConfig->batteryCurrentAvgPath = path;
                }//!< 查找current_avg 若存在配置路径 
                if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
                    path.clear();
                    path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
                                      name);
                    if (access(path, R_OK) == 0) {
                        mHealthdConfig->batteryTemperaturePath = path;
                    }
                }//!< 查找temp 若存在配置路径 

                break;

            case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
                break;
            }
        }
    }
	 //!< 无电池状态,长供电设备 
    if (!mBatteryDevicePresent) {
        KLOG_WARNING(LOG_TAG, "No battery devices found\n");
        hc->periodic_chores_interval_fast = -1;
        hc->periodic_chores_interval_slow = -1;
    } else {
        if (mHealthdConfig->batteryStatusPath.isEmpty())
            KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
            。。。
     //!< 不存在的属性 log输出 
    }

    if (property_get("ro.boot.fake_battery", pval, NULL) > 0
                                               && strtol(pval, NULL, 10) != 0) {
        mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
        mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
    }
}

Update函数

bool BatteryMonitor::update(void) {
    bool logthis;

    initBatteryProperties(&props);
 //!< 赋初值,设置属性为0活false 
    if (!mHealthdConfig->batteryPresentPath.isEmpty())
        props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
    else
        props.batteryPresent = mBatteryDevicePresent;
 //!< 通过获取到的路径,读取节点属性 进行更新 
    props.batteryLevel = mBatteryFixedCapacity ?
        mBatteryFixedCapacity :
        getIntField(mHealthdConfig->batteryCapacityPath);
    props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
 //!< 若存Capacity 属性  在根据读到的值 计算容量 
    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
        props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath) / 1000;
 //!< 同上 By: jixuan 2021年6月10日
    if (!mHealthdConfig->batteryFullChargePath.isEmpty())
        props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath);
 //!< 同上 By: jixuan 2021年6月10日
    if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
        props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);

    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
        props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);

    props.batteryTemperature = mBatteryFixedTemperature ?
        mBatteryFixedTemperature :
        getIntField(mHealthdConfig->batteryTemperaturePath);

    std::string buf;

    if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
        props.batteryStatus = getBatteryStatus(buf.c_str());
  //!< 若存在status,更新status
    if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
        props.batteryHealth = getBatteryHealth(buf.c_str());
  //!< 若存在Health,更新Health 
    unsigned int i;
    double MaxPower = 0;
    for (i = 0; i < mChargerNames.size(); i++) {
	//!< 解析每一个power Charger type 
        String8 path;
        path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
                          mChargerNames[i].string());
        if (getIntField(path)) {
            path.clear();
            path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
                              mChargerNames[i].string());
            switch(readPowerSupplyType(path)) {
		 //!< 判断是哪种power supply type By: jixuan 2021年6月10日
            case ANDROID_POWER_SUPPLY_TYPE_AC:
                props.chargerAcOnline = true;
                break;
            case ANDROID_POWER_SUPPLY_TYPE_USB:
                props.chargerUsbOnline = true;
                break;
            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
                props.chargerWirelessOnline = true;
                break;
            default:
                KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
                             mChargerNames[i].string());
            }
            path.clear();
            path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
                              mChargerNames[i].string());
            int ChargingCurrent =
                    (access(path.string(), R_OK) == 0) ? getIntField(path) : 0;

            path.clear();
            path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
                              mChargerNames[i].string());

            int ChargingVoltage =
                (access(path.string(), R_OK) == 0) ? getIntField(path) :
                DEFAULT_VBUS_VOLTAGE;

            double power = ((double)ChargingCurrent / MILLION) *
                           ((double)ChargingVoltage / MILLION);
            if (MaxPower < power) {
                props.maxChargingCurrent = ChargingCurrent;
                props.maxChargingVoltage = ChargingVoltage;
                MaxPower = power;
            }
        }
    }

	if(!mBatteryDevicePresent) {
        props.batteryPresent = true;
        props.batteryStatus = 3;
        props.batteryHealth = 2;
        props.batteryLevel = 80;
        props.batteryVoltage = 4000;
        props.batteryTemperature = 250;
        props.batteryCurrent = 288;
        props.batteryCycleCount = 0;
        props.batteryFullCharge = 3481000;
        props.batteryChargeCounter = 2828520;
        props.batteryTechnology = "Li-ion";
    }
 //!< 配置默认值 
    logthis = !healthd_board_battery_update(&props);

   if (logthis) {
 //!< 若需要监听Battery相关的状态log,可以从这里输出
        char dmesgline[256];
        size_t len;
        if (props.batteryPresent) {
            snprintf(dmesgline, sizeof(dmesgline),
                 "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
                 props.batteryLevel, props.batteryVoltage,
                 props.batteryTemperature < 0 ? "-" : "",
                 abs(props.batteryTemperature / 10),
                 abs(props.batteryTemperature % 10), props.batteryHealth,
                 props.batteryStatus);

            len = strlen(dmesgline);
            if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
                                " c=%d", props.batteryCurrent);
            }

            if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
                                " fc=%d", props.batteryFullCharge);
            }

            if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
                                " cc=%d", props.batteryCycleCount);
            }
        } else {
            len = snprintf(dmesgline, sizeof(dmesgline),
                 "battery none");
        }
        snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
                 props.chargerAcOnline ? "a" : "",
                 props.chargerUsbOnline ? "u" : "",
                 props.chargerWirelessOnline ? "w" : "");

        KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
    }
 //!< 输出此刻读取到的状态 
    healthd_mode_ops->battery_update(&props);
 //!< 调用update 接口上报更新
    return props.chargerAcOnline | props.chargerUsbOnline |
            props.chargerWirelessOnline;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值