本文主要是介绍【Android 10 源码】healthd 模块 HAL 1.0 分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
health@1.0:android.hardware.health@1.0 的缩写。指的是 Android 8.0 中发布的运行状况 HIDL 的 1.0 版 HAL。
Android 8.x 中的“运行状况”服务
在 Android 8.x 中,运行状况组件的工作原理详情如下图所示:
在此图中:
- 框架通过一次 Binder 调用和一次 hwbinder 调用与硬件进行通信。
- healthd 静态关联到 libhealthd_android、libbatterymonitor 和 libbatteryservice。
- health@1.0-impl 静态关联到 libhealthd.BOARD。
每个开发板都可以自定义不同的 libhealthd.BOARD;charger、health@1.0-impl 和 recovery 关联到哪个开发板是在构建时确定的。
对于其他模式:
charger 静态关联到 libhealthd.BOARD、libhealthd_charger 和 libbatterymonitor。
recovery 静态关联到 libhealthd.BOARD 和 libbatterymonitor。
health@1.0 HAL 中的定义:
hardware/interfaces/health/1.0/types.hal
package android.hardware.health@1.0;/*** Possible return values for optional HAL method(s) like* IHealth::energyCounter()* 可选HAL方法的可能返回值*/
enum Result : int32_t {SUCCESS,NOT_SUPPORTED,UNKNOWN,
};/*** Possible values for Battery Status.* “电池状态”的取值范围。* Note: These are currently in sync with BatteryManager and must not* be extended / altered.* 注意:这些目前与 BatteryManager 同步,不能扩展/更改。*/
@export(name="", value_prefix="BATTERY_STATUS_")
enum BatteryStatus : int32_t {UNKNOWN = 1,CHARGING = 2,DISCHARGING = 3,/*** Battery is *not* charging - special case when charger is present* but battery isn't charging*/NOT_CHARGING = 4,FULL = 5,
};/*** Possible values for Battery Health.* 电池运行状况的可能值。* Note: These are currently in sync with BatteryManager and must not* be extended / altered.* 注意:这些目前与 BatteryManager 同步,不能扩展/更改。*/
@export(name="", value_prefix="BATTERY_HEALTH_")
enum BatteryHealth : int32_t {UNKNOWN = 1,GOOD = 2,OVERHEAT = 3,DEAD = 4,OVER_VOLTAGE = 5,/*** Battery experienced an unknown/unspecifid failure.*/UNSPECIFIED_FAILURE = 6,COLD = 7,
};struct HealthConfig {/*** periodicChoresIntervalFast is used while the device is not in* suspend, or in suspend and connected to a charger (to watch for battery* overheat due to charging)* 当设备不处于挂起状态或挂起并连接到充电器时使用 periodicChoresIntervalFast* (观察电池因充电而过热)*/int32_t periodicChoresIntervalFast;/*** periodicChoresIntervalSlow is used when the device is in suspend and* not connected to a charger (to watch for a battery drained to zero* remaining capacity).* 当设备处于挂起状态且未连接充电器时,* 使用 periodicChoresIntervalSlow (观察电池耗尽至剩余容量为零)。*/int32_t periodicChoresIntervalSlow;/*** power_supply sysfs attribute file paths. Set these to specific paths* to use for the associated battery parameters. Clients must search* for appropriate power_supply attribute files to use, for any paths* left empty after the HAL is initialized.*//*** batteryStatusPath - file path to read battery charging status.* 读取电池充电状态的文件路径。* (POWER_SUPPLY_PROP_STATUS)*/string batteryStatusPath;/*** batteryHealthPath - file path to read battery health.* 读取电池运行状况的文件路径。* (POWER_SUPPLY_PROP_HEALTH)*/string batteryHealthPath;/*** batteryPresentPath - file path to read battery present status.* 读取电池当前状态的文件路径。* (POWER_SUPPLY_PROP_PRESENT)*/string batteryPresentPath;/*** batteryCapacityPath - file path to read remaining battery capacity.* 读取剩余电池容量的文件路径。* (POWER_SUPPLY_PROP_CAPACITY)*/string batteryCapacityPath;/*** batteryVoltagePath - file path to read battery voltage.* 读取电池电压的文件路径。* (POWER_SUPPLY_PROP_VOLTAGE_NOW)*/string batteryVoltagePath;/*** batteryTemperaturePath - file path to read battery temperature in tenths* of degree celcius. (POWER_SUPPLY_PROP_TEMP)* 读取电池温度摄氏度乘以10后的文件路径。*/string batteryTemperaturePath;/*** batteryTechnologyPath - file path to read battery technology.* 读取电池技术的文件路径。* (POWER_SUPPLY_PROP_TECHNOLOGY)*/string batteryTechnologyPath;/*** batteryCurrentNowPath - file path to read battery instantaneous current.* 读取电池瞬时电流的文件路径。* (POWER_SUPPLY_PROP_CURRENT_NOW)*/string batteryCurrentNowPath;/*** batteryCurrentAvgPath - file path to read battery average current.* 读取电池平均电流的文件路径。* (POWER_SUPPLY_PROP_CURRENT_AVG)*/string batteryCurrentAvgPath;/*** batteryChargeCounterPath - file path to read battery accumulated charge.* 读取电池累计充电电量的文件路径。* (POWER_SUPPLY_PROP_CHARGE_COUNTER)*/string batteryChargeCounterPath;/*** batteryFullChargerPath - file path to read battery charge value when it* is considered to be full. (POWER_SUPPLY_PROP_CHARGE_FULL)* 读取电池充满时的对应值文件路径。*/string batteryFullChargePath;/*** batteryCycleCountPath - file path to read battery charge cycle count.* 读取电池充电周期计数文件路径。* (POWER_SUPPLY_PROP_CYCLE_COUNT)*/string batteryCycleCountPath;
};/*** The parameter to healthd mainloop update calls* healthd 主循环更新调用的参数*/
struct HealthInfo {/** AC charger state - 'true' if online */ /** 交流充电状态 */bool chargerAcOnline;/** USB charger state - 'true' if online */ /** USB 充电状态 */bool chargerUsbOnline;/** Wireless charger state - 'true' if online */ /** 无线充电状态 */bool chargerWirelessOnline;/** Maximum charging current supported by charger in uA *//** 充电器支持的最大充电电流(uA) */int32_t maxChargingCurrent;/** Maximum charging voltage supported by charger in uV *//** 充电器支持的最大充电电压(uV) */int32_t maxChargingVoltage;BatteryStatus batteryStatus;BatteryHealth batteryHealth;/** 'true' if battery is present *//** 如果有电池,则为 true */bool batteryPresent;/** Remaining battery capacity in percent *//** 剩余电池容量百分比 */int32_t batteryLevel;/*** Instantaneous battery voltage in millivolts (mV).* 瞬间电池电压(毫伏)。** Historically, the unit of this field is microvolts (uV), but all* clients and implementations uses millivolts in practice, making it* the de-facto standard.*/int32_t batteryVoltage;/** Instantaneous battery temperature in tenths of degree celcius *//** 瞬间电池温度 */int32_t batteryTemperature;/** Instantaneous battery current in uA *//** 瞬时电池电流(uA) */int32_t batteryCurrent;/** Battery charge cycle count *//** 电池充电周期计数 */int32_t batteryCycleCount;/** Battery charge value when it is considered to be "full" in uA-h *//** 当认为电池“满”时的电池充电值(uA-h) */int32_t batteryFullCharge;/** Instantaneous battery capacity in uA-h *//** 瞬时电池容量(uA-h) */int32_t batteryChargeCounter;/** Battery technology, e.g. "Li-ion, Li-Poly" etc. *//** 电池技术 */string batteryTechnology;
};
hardware/interfaces/health/1.0/IHealth.hal
package android.hardware.health@1.0;interface IHealth {/*** This function lets you change healthd configuration from default if* desired. It must be called exactly once at startup time.* 如果需要,这个功能可以让你改变默认的 healthd 配置。它必须在启动时调用一次。** The configuration values are described in 'struct HealthConfig'.* To use default configuration, simply return without modifying the* fields of the config parameter.* 配置值在“struct HealthConfig”中描述。* 要使用默认配置,只需返回而不修改 config 参数的字段。** @param default healthd configuration.*/init(HealthConfig config) generates (HealthConfig configOut);/*** This function is a hook to update/change device's HealthInfo (as described* in 'struct HealthInfo').* 这个函数是一个 hook 来更新/改变设备的 HealthInfo** 'HealthInfo' describes device's battery and charging status, typically* read from kernel. These values may be modified in this call.* “HealthInfo”描述设备的电池和充电状态,通常从内核读取。* 这些值可以在这个调用中修改。** @param Device Health info as described in 'struct HealthInfo'.* @return skipLogging Indication to the caller to add 'or' skip logging the health* information. Return 'true' to skip logging the update.* @return infoOut HealthInfo to be sent to client code. (May or may* not be modified).*/update(HealthInfo info) generates (bool skipLogging, HealthInfo infoOut);/*** This function is called by healthd when framework queries for remaining* energy in the Battery through BatteryManager APIs.* 当框架通过 BatteryManager API 查询电池中的剩余电量时,* healthd 会调用这个函数。** @return result Result of querying enery counter for the battery.* @return energy Battery remaining energy in nanowatt-hours.* Must be '0' if result is anything other than Result::SUCCESS.*/energyCounter() generates (Result result, int64_t energy);
};
现在重点来分析 hardware/interfaces/health/1.0/default/ 下的实现。Android.mk 中编译了两个模块,分别为 android.hardware.health@1.0-impl 和 android.hardware.health@1.0-service(可执行文件)。android.hardware.health@1.0-impl 主要使用了 Health.cpp 源文件,android.hardware.health@1.0-service 则使用了 HealthService.cpp 源文件。
hardware/interfaces/health/1.0/default/Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.health@1.0-impl
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := system/core/base/include
LOCAL_SRC_FILES := \Health.cpp \LOCAL_HEADER_LIBRARIES := libhealthd_headersLOCAL_SHARED_LIBRARIES := \libcutils \libhidlbase \libhidltransport \liblog \libutils \android.hardware.health@1.0 \LOCAL_STATIC_LIBRARIES := android.hardware.health@1.0-convertLOCAL_HAL_STATIC_LIBRARIES := libhealthdinclude $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE := android.hardware.health@1.0-service
LOCAL_INIT_RC := android.hardware.health@1.0-service.rc
LOCAL_SRC_FILES := \HealthService.cpp \LOCAL_SHARED_LIBRARIES := \liblog \libcutils \libdl \libbase \libutils \libhidlbase \libhidltransport \android.hardware.health@1.0 \include $(BUILD_EXECUTABLE)include $(call first-makefiles-under,$(LOCAL_PATH))
android.hardware.health@1.0-impl 包含了 HAL 的实现以及一个导出函数 HIDL_FETCH_IHealth(…) ,HIDL_FETCH_IHealth(…) 获取 HAL 实现的对象,只是 new 了一个 Health 结构体返回。
Health::init(…) 实现主要流程:
- 创建一个 healthd_config struct;
- 为了使得 healthd 静态 HAL 工作正常,调用 convertFromHealthConfig(…) 将 HealthConfig 转换为 healthd_config;
- 调用 healthd_board_init(…) 进一步板级初始化;
- 给 mGetEnergyCounter 字段赋值;
- 调用 convertToHealthConfig(…) 再将 healthd_config 转换为 HealthConfig 结构,并返回。
Health::update(…) 实现主要流程:
- 创建 android::BatteryProperties 结构;
- 调用 convertFromHealthInfo(…) 将 HealthInfo 转为 android::Batteryproperties;
- 调用板级更新 healthd_board_battery_update(…);
- 调用 convertToHealthInfo(…) 将 android::Batteryproperties 转为 HealthInfo。
Health::energyCounter(…) 实现非常简单主要调用了 mGetEnergyCounter 指向的函数指针获取剩余电量。
hardware/interfaces/health/1.0/default/Health.cpp
using ::android::hardware::health::V1_0::hal_conversion::convertToHealthConfig;
using ::android::hardware::health::V1_0::hal_conversion::convertFromHealthConfig;
using ::android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
using ::android::hardware::health::V1_0::hal_conversion::convertFromHealthInfo;// Methods from ::android::hardware::health::V1_0::IHealth follow.
Return<void> Health::init(const HealthConfig& config, init_cb _hidl_cb) {struct healthd_config healthd_config = {};HealthConfig configOut;// To keep working with existing healthd static HALs,// convert the new HealthConfig to the old healthd_config// and back.convertFromHealthConfig(config, &healthd_config);healthd_board_init(&healthd_config);mGetEnergyCounter = healthd_config.energyCounter;convertToHealthConfig(&healthd_config, configOut);_hidl_cb(configOut);return Void();
}Return<void> Health::update(const HealthInfo& info, update_cb _hidl_cb) {struct android::BatteryProperties p = {};HealthInfo infoOut;// To keep working with existing healthd static HALs,// convert the new HealthInfo to android::Batteryproperties// and back.convertFromHealthInfo(info, &p);int skipLogging = healthd_board_battery_update(&p);convertToHealthInfo(&p, infoOut);_hidl_cb(!!skipLogging, infoOut);return Void();
}Return<void> Health::energyCounter(energyCounter_cb _hidl_cb) {int64_t energy = 0;Result result = Result::NOT_SUPPORTED;if (mGetEnergyCounter) {int status = mGetEnergyCounter(&energy);if (status == 0) {result = Result::SUCCESS;}}_hidl_cb(result, energy);return Void();
}IHealth* HIDL_FETCH_IHealth(const char* /* name */) {return new Health();
}
上面提到的转换适配函数定义在 convert.cpp 中,实现了 healthd_config 和 HealthConfig 互转,
BatteryProperties 和 HealthInfo 互转。
hardware/interfaces/health/1.0/default/convert.cpp
void convertToHealthConfig(const struct healthd_config *hc, HealthConfig& config) {config.periodicChoresIntervalFast = hc->periodic_chores_interval_fast;config.periodicChoresIntervalSlow = hc->periodic_chores_interval_slow;config.batteryStatusPath = hc->batteryStatusPath.string();config.batteryHealthPath = hc->batteryHealthPath.string();config.batteryPresentPath = hc->batteryPresentPath.string();config.batteryCapacityPath = hc->batteryCapacityPath.string();config.batteryVoltagePath = hc->batteryVoltagePath.string();config.batteryTemperaturePath = hc->batteryTemperaturePath.string();config.batteryTechnologyPath = hc->batteryTechnologyPath.string();config.batteryCurrentNowPath = hc->batteryCurrentNowPath.string();config.batteryCurrentAvgPath = hc->batteryCurrentAvgPath.string();config.batteryChargeCounterPath = hc->batteryChargeCounterPath.string();config.batteryFullChargePath = hc->batteryFullChargePath.string();config.batteryCycleCountPath = hc->batteryCycleCountPath.string();}void convertFromHealthConfig(const HealthConfig& c, struct healthd_config *hc) {hc->periodic_chores_interval_fast = c.periodicChoresIntervalFast;hc->periodic_chores_interval_slow = c.periodicChoresIntervalSlow;hc->batteryStatusPath =android::String8(c.batteryStatusPath.c_str(),c.batteryStatusPath.size());hc->batteryHealthPath =android::String8(c.batteryHealthPath.c_str(),c.batteryHealthPath.size());hc->batteryPresentPath =android::String8(c.batteryPresentPath.c_str(),c.batteryPresentPath.size());hc->batteryCapacityPath =android::String8(c.batteryCapacityPath.c_str(),c.batteryCapacityPath.size());hc->batteryVoltagePath =android::String8(c.batteryVoltagePath.c_str(),c.batteryVoltagePath.size());hc->batteryTemperaturePath =android::String8(c.batteryTemperaturePath.c_str(),c.batteryTemperaturePath.size());hc->batteryTechnologyPath =android::String8(c.batteryTechnologyPath.c_str(),c.batteryTechnologyPath.size());hc->batteryCurrentNowPath =android::String8(c.batteryCurrentNowPath.c_str(),c.batteryCurrentNowPath.size());hc->batteryCurrentAvgPath =android::String8(c.batteryCurrentAvgPath.c_str(),c.batteryCurrentNowPath.size());hc->batteryChargeCounterPath =android::String8(c.batteryChargeCounterPath.c_str(),c.batteryChargeCounterPath.size());hc->batteryFullChargePath =android::String8(c.batteryFullChargePath.c_str(),c.batteryFullChargePath.size());hc->batteryCycleCountPath =android::String8(c.batteryCycleCountPath.c_str(),c.batteryCycleCountPath.size());// energyCounter is handled through special means so all calls to// the function go across the HALs// boot_min_cap - never used in Android (only in charger-mode).// screen_on - never used in Android (only in charger mode).
}void convertToHealthInfo(const struct android::BatteryProperties *p,HealthInfo& info) {info.chargerAcOnline = p->chargerAcOnline;info.chargerUsbOnline = p->chargerUsbOnline;info.chargerWirelessOnline = p->chargerWirelessOnline;info.maxChargingCurrent = p->maxChargingCurrent;info.maxChargingVoltage = p->maxChargingVoltage;info.batteryStatus = static_cast<BatteryStatus>(p->batteryStatus);info.batteryHealth = static_cast<BatteryHealth>(p->batteryHealth);info.batteryPresent = p->batteryPresent;info.batteryLevel = p->batteryLevel;info.batteryVoltage = p->batteryVoltage;info.batteryTemperature = p->batteryTemperature;info.batteryCurrent = p->batteryCurrent;info.batteryCycleCount = p->batteryCycleCount;info.batteryFullCharge = p->batteryFullCharge;info.batteryChargeCounter = p->batteryChargeCounter;info.batteryTechnology = p->batteryTechnology;
}void convertFromHealthInfo(const HealthInfo& info,struct android::BatteryProperties *p) {p->chargerAcOnline = info.chargerAcOnline;p->chargerUsbOnline = info.chargerUsbOnline;p->chargerWirelessOnline = info.chargerWirelessOnline;p->maxChargingCurrent = info.maxChargingCurrent;p->maxChargingVoltage = info.maxChargingVoltage;p->batteryStatus = static_cast<int>(info.batteryStatus);p->batteryHealth = static_cast<int>(info.batteryHealth);p->batteryPresent = info.batteryPresent;p->batteryLevel = info.batteryLevel;p->batteryVoltage = info.batteryVoltage;p->batteryTemperature = info.batteryTemperature;p->batteryCurrent = info.batteryCurrent;p->batteryCycleCount = info.batteryCycleCount;p->batteryFullCharge = info.batteryFullCharge;p->batteryChargeCounter = info.batteryChargeCounter;p->batteryTechnology = android::String8(info.batteryTechnology.c_str());
}
libhealthd 模块 Android.bp 编译主要使用了 healthd_board_default.cpp。
hardware/interfaces/health/1.0/default/libhealthd/Android.bp
cc_library_static {srcs: ["healthd_board_default.cpp"],name: "libhealthd.default",vendor_available: true,recovery_available: true,cflags: ["-Werror"],include_dirs: ["system/core/base/include"],header_libs: ["libhealthd_headers"],
}
healthd_board_init(…) 和 healthd_board_battery_update(…) 仅仅都是空实现。
hardware/interfaces/health/1.0/default/libhealthd/healthd_board_default.cpp
void healthd_board_init(struct healthd_config*)
{// use defaults
}int healthd_board_battery_update(struct android::BatteryProperties*)
{// return 0 to log periodic polled battery status to kernel logreturn 0;
}
android.hardware.health@1.0-service 实现了 HAL service。主要使用了 HealthService.cpp 源文件和,关联了 android.hardware.health@1.0-service.rc 文件。
Binderized 绑定式可以用两种方式来绑定服务,第一种通过 defaultPassthroughServiceImplementation 调用来注册服务,另外一种是直接调用 RegisterAsService 来注册服务。此处显然是通过第一种。
hardware/interfaces/health/1.0/default/HealthService.cpp
using android::hardware::health::V1_0::IHealth;
using android::hardware::defaultPassthroughServiceImplementation;int main() {return defaultPassthroughServiceImplementation<IHealth>();
}
rc 文件中,class 分类为 hal,user 用户是 system,group 组也是 system,capabilities 能力则是 WAKE_ALARM,表明可以闹钟唤醒。系统启动后 vendor.health-hal-1-0 Service 将会注册到系统。
hardware/interfaces/health/1.0/default/android.hardware.health@1.0-service.rc
service vendor.health-hal-1-0 /vendor/bin/hw/android.hardware.health@1.0-serviceclass haluser systemgroup systemcapabilities WAKE_ALARM
Android.bp 文件中编译了 android.hardware.health@1.0-convert 静态库,它主要使用了 convert.cpp 文件。
hardware/interfaces/health/1.0/default/Android.bp
cc_library_static {name: "android.hardware.health@1.0-convert",vendor_available: true,recovery_available: true,srcs: ["convert.cpp"],include_dirs: ["system/core/base/include",],header_libs: ["libhealthd_headers"],export_header_lib_headers: ["libhealthd_headers"],export_include_dirs: ["include"],shared_libs: ["libcutils","libhidlbase","libhidltransport","libutils","android.hardware.health@1.0",],}
这篇关于【Android 10 源码】healthd 模块 HAL 1.0 分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!