参考:https://blog.csdn.net/u012830148/article/details/80226498
healthd
healthd是安卓4.4之后提出来的,监听来自kernel的电池事件,并向上传递电池数据给framework层的BatteryService。BatteryService计算电池电量显示,剩余电量,电量级别以及绘制充电动画等信息,其代码位于/system/core/healthd。
android/system/core/healthd/ Android.mk BatteryMonitor.h BatteryPropertiesRegistrar.h healthd.cpp healthd_mode_android.cpp images BatteryMonitor.cpp BatteryPropertiesRegistrar.cpp healthd_board_default.cpp healthd.h healthd_mode_charger.cpp
下面一张图清晰的表示了Android电池系统框架
healthd服务入口:android/system/core/healthd/healthd.cpp 中main函数。
-
int main(
int argc,
char **argv) {
-
int ch;
-
int ret;
-
-
klog_set_level(KLOG_LEVEL);
-
-
-
//healthd_mode_ops是一个关于充电状态的结构体变量,
-
healthd_mode_ops = &android_ops;
//开机充电时,指向android_ops
-
-
if (!strcmp(basename(argv[
0]),
"charger")) {
-
healthd_mode_ops = &charger_ops;
//
-
}
else {
-
while ((ch = getopt(argc, argv,
"cr")) !=
-1) {
-
switch (ch) {
-
case
'c':
-
healthd_mode_ops = &charger_ops;
//关机状态下的充电
-
break;
-
case
'r':
-
healthd_mode_ops = &recovery_ops;
//recovery下的操作
-
break;
-
case
'?':
-
default:
-
KLOG_ERROR(LOG_TAG,
"Unrecognized healthd option: %c\n",
-
optopt);
-
exit(
1);
-
}
-
}
-
}
-
-
ret = healthd_init();
//healthed初始化
-
if (ret) {
-
KLOG_ERROR(
"Initialization failed, exiting\n");
-
exit(
2);
-
}
-
-
healthd_mainloop();
//主循环
-
KLOG_ERROR(
"Main loop terminated, exiting\n");
-
return
3;
-
}
在main函数中,首先根据传入的参数不同区分:开机充电、recovery、关机充电。这三种情况,然后指定不同的healthd_mode_ops回调函数。因此有必要贴出来这三个重要的回调。
-
///三个相关的ops
-
static
struct healthd_mode_ops android_ops = { 开机充电
-
.init = healthd_mode_android_init,
-
.preparetowait = healthd_mode_android_preparetowait,
-
.heartbeat = healthd_mode_nop_heartbeat,
-
.battery_update = healthd_mode_android_battery_update,
-
};
-
-
static
struct healthd_mode_ops charger_ops = { 关机充电
-
.init = healthd_mode_charger_init,
-
.preparetowait = healthd_mode_charger_preparetowait,
-
.heartbeat = healthd_mode_charger_heartbeat,
-
.battery_update = healthd_mode_charger_battery_update,
-
};
-
-
static
struct healthd_mode_ops recovery_ops = { recover相关的
-
.init = healthd_mode_nop_init,
-
.preparetowait = healthd_mode_nop_preparetowait,
-
.heartbeat = healthd_mode_nop_heartbeat,
-
.battery_update = healthd_mode_nop_battery_update,
-
};
接着往下看healthd_init()
-
static
int healthd_init() {
-
epollfd = epoll_create(MAX_EPOLL_EVENTS);
//创建一个epoll变量
-
if (epollfd ==
-1) {
-
KLOG_ERROR(LOG_TAG,
-
"epoll_create failed; errno=%d\n",
-
errno);
-
return
-1;
-
}
-
//和板子级别的初始化,里面其实是一个空函数,什么也没做
-
healthd_board_init(&healthd_config);
-
//根据系统所处的模式,有三种情况的init,开机充电,关机充电,recovery
-
healthd_mode_ops->init(&healthd_config);
-
//wakealarm定时器初始化
-
wakealarm_init();
-
//uevent事件初始化,用以监听电池的uevent事件。
-
uevent_init();
-
//BatteryMonitor初始化。
-
gBatteryMonitor = new BatteryMonitor();
//创建batteryMonitor对象
-
gBatteryMonitor->init(&healthd_config);
//初始化batteryMonitor,打开/sys/class/power_supply,
-
//遍历该节点下的电池参数初始化healthd的config参数
-
return
0;
-
}
healthd_mode_ops->init(&healthd_config);根据main函数中传入的参数 有三种模式,Android,charger,recovery。
-
android模式
-
void healthd_mode_android_init(
struct healthd_config*
/*config*/) {
-
ProcessState::
self()->setThreadPoolMaxThreadCount(
0);
//获取线程池最大线程数
-
IPCThreadState::
self()->disableBackgroundScheduling(
true);
//禁止后台调用
-
IPCThreadState::
self()->setupPolling(&gBinderFd);
//将gBinderFd加入到epoll中
-
-
if (gBinderFd >=
0) {
-
//将binder_event事件注册到gBinderfd文件节点用以监听Binder事件。
-
if (healthd_register_event(gBinderFd, binder_event))
-
KLOG_ERROR(LOG_TAG,
-
"Register for binder events failed\n");
-
}
-
-
gBatteryPropertiesRegistrar = new BatteryPropertiesRegistrar();
-
//将batteryProperties注册到ServiceManager中
-
gBatteryPropertiesRegistrar->publish();
-
}
charger模式就是关机充电模式,Android层只跑一个healthd服务用来显示充电动画和电量百分比。
-
charger模式
-
-
void healthd_mode_charger_init(
struct healthd_config* config)
//做充电动画相关的设置
-
{
-
int ret;
-
struct charger *charger = &charger_state;
-
int i;
-
int epollfd;
-
-
dump_last_kmsg();
-
-
LOGW(
"--------------- STARTING CHARGER MODE ---------------\n");
-
-
ret = ev_init(input_callback, charger);
-
if (!ret) {
-
epollfd = ev_get_epollfd();
-
healthd_register_event(epollfd, charger_event_handler);
-
}
-
-
ret = res_create_display_surface(
"charger/battery_fail", &charger->surf_unknown);
-
if (ret <
0) {
-
LOGE(
"Cannot load battery_fail image\n");
-
charger->surf_unknown =
NULL;
-
}
-
-
charger->batt_anim = &battery_animation;
//指定充电动画相关的属性
-
-
gr_surface* scale_frames;
-
int scale_count;
-
ret = res_create_multi_display_surface(
"charger/battery_scale", &scale_count, &scale_frames);
//读取充电动画资源
-
if (ret <
0) {
-
LOGE(
"Cannot load battery_scale image\n");
-
charger->batt_anim->num_frames =
0;
-
charger->batt_anim->num_cycles =
1;
-
}
else
if (scale_count != charger->batt_anim->num_frames) {
-
LOGE(
"battery_scale image has unexpected frame count (%d, expected %d)\n",
-
scale_count, charger->batt_anim->num_frames);
-
charger->batt_anim->num_frames =
0;
-
charger->batt_anim->num_cycles =
1;
-
}
else {
-
for (i =
0; i < charger->batt_anim->num_frames; i++) {
//读取资源成功,存放起来
-
charger->batt_anim->frames[i].surface = scale_frames[i];
-
}
-
}
-
-
ev_sync_key_state(set_key_callback, charger);
-
-
charger->next_screen_transition =
-1;
-
charger->next_key_check =
-1;
-
charger->next_pwr_check =
-1;
-
healthd_config = config;
-
}
-
//接着到wakealarm_init
-
static
void wakealarm_init(
void) {
-
//创建一个月wakealarm对应的定时器描述符
-
wakealarm_fd = timerfd_create(
CLOCK_BOOTTIME_ALARM, TFD_NONBLOCK);
-
if (wakealarm_fd ==
-1) {
-
KLOG_ERROR(LOG_TAG,
"wakealarm_init: timerfd_create failed\n");
-
return;
-
}
-
//将wakealarm事件注册到wakealarm_fd文件节点上以监听wakealarm事件。
-
if (healthd_register_event(wakealarm_fd, wakealarm_event))
-
KLOG_ERROR(LOG_TAG,
-
"Registration of wakealarm event failed\n");
-
//设置alarm唤醒间隔
-
wakealarm_set_interval(healthd_config.periodic_chores_interval_fast);
-
}
-
static
void uevent_init(
void) {
-
//创建并打开一个socket文件描述符uevent_fd
-
uevent_fd = uevent_open_socket(
64*
1024,
true);
-
-
if (uevent_fd <
0) {
-
KLOG_ERROR(LOG_TAG,
"uevent_init: uevent_open_socket failed\n");
-
return;
-
}
-
//将其设置为非阻塞模式
-
fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
-
//将其注册到healthed_init创建的描述符集合里
-
if (healthd_register_event(uevent_fd, uevent_event))
-
KLOG_ERROR(LOG_TAG,
-
"register for uevent events failed\n");
-
}
-
static
void healthd_mainloop(
void) {
-
while (
1) {
-
struct epoll_event events[eventct];
-
int nevents;
-
int timeout = awake_poll_interval;
-
int mode_timeout;
-
//获取等待事件的超时时间,events是从epollfd上轮询的中监听得到的事件数目。
-
mode_timeout = healthd_mode_ops->preparetowait();
-
if (timeout <
0 || (mode_timeout >
0 && mode_timeout < timeout))
-
timeout = mode_timeout;
-
//接收event事件
-
nevents = epoll_wait(epollfd, events, eventct, timeout);
-
-
if (nevents ==
-1) {
-
if (errno == EINTR)
-
continue;
-
KLOG_ERROR(LOG_TAG,
"healthd_mainloop: epoll_wait failed\n");
-
break;
-
}
-
//遍历处理每一个事件
-
for (
int n =
0; n < nevents; ++n) {
-
if (events[n].data.ptr)
-
(*(
void (*)(
int))events[n].data.ptr)(events[n].events);
-
}
-
//如果有事件发生,更新电池状态
-
if (!nevents)
-
periodic_chores();
//更新电池状态信息
-
healthd_battery_update();
-
-
healthd_mode_ops->heartbeat();
//如果是在关机充电模式的话去绘制充电动画。
-
//开机充电的话则不做任何事情。
-
}
-
-
return;
-
}
如果是关机充电模式,则healthd_mode_ops->heartbeat(); 执行的是healthd_mode_charger_heartbeat()函数
-
void healthd_mode_charger_heartbeat()
-
{
-
struct charger *charger = &charger_state;
-
int64_t now = curr_time_ms();
-
int ret;
-
-
handle_input_state(charger, now);
//处理按键相关的事情,长按开机
-
handle_power_supply_state(charger, now);
-
-
/* do screen update last in case any of the above want to start
-
* screen transitions (animations, etc)
-
*/
-
update_screen_state(charger, now);
//绘制充电动画
-
}
-
frameworks/base/services/core/java/com/android/server/BatteryService.java
-
//将电池监听注册到底层
-
public
void onStart() {
-
IBinder b = ServiceManager.getService(
"batteryproperties");
-
final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
-
IBatteryPropertiesRegistrar.Stub.asInterface(b);
-
try {
-
//注册电池监听,当底层电池电量发生变化调用此监听,并调用update。
-
batteryPropertiesRegistrar.registerListener(new BatteryListener());
-
} catch (RemoteException e) {
-
// Should never happen.
-
}
-
-
publishBinderService(
"battery", new BinderService());
-
publishLocalService(BatteryManagerInternal.class, new LocalService());
-
}
-
//当底层有信息时,会调用update更新BatteryService中相关值。
-
private
void update(BatteryProperties props) {
-
synchronized (mLock) {
-
if (!mUpdatesStopped) {
-
mBatteryProps = props;
-
// Process the new values.
-
processValuesLocked(
false);
-
}
else {
-
mLastBatteryProps.set(props);
-
}
-
}
-
}
-
private
void processValuesLocked(boolean force) {
-
boolean logOutlier =
false;
-
long dischargeDuration =
0;
-
//获取电池电量是否低于critical界限。
-
mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
-
//获取电池充电状态,AC,USB,无线,以及什么都没接。
-
if (mBatteryProps.chargerAcOnline) {
-
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
-
}
else
if (mBatteryProps.chargerUsbOnline) {
-
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
-
}
else
if (mBatteryProps.chargerWirelessOnline) {
-
mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
-
}
else {
-
mPlugType = BATTERY_PLUGGED_NONE;
-
}
-
-
if (DEBUG) {
-
Slog.d(TAG,
"Processing new values: "
-
+
"chargerAcOnline=" + mBatteryProps.chargerAcOnline
-
+
", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
-
+
", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
-
+
", batteryStatus=" + mBatteryProps.batteryStatus
-
+
", batteryHealth=" + mBatteryProps.batteryHealth
-
+
", batteryPresent=" + mBatteryProps.batteryPresent
-
+
", batteryLevel=" + mBatteryProps.batteryLevel
-
+
", batteryTechnology=" + mBatteryProps.batteryTechnology
-
+
", batteryVoltage=" + mBatteryProps.batteryVoltage
-
+
", batteryTemperature=" + mBatteryProps.batteryTemperature
-
+
", mBatteryLevelCritical=" + mBatteryLevelCritical
-
+
", mPlugType=" + mPlugType);
-
}
-
-
// Let the battery stats keep track of the current level.
-
try {
-
mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
-
mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
-
mBatteryProps.batteryVoltage);
-
} catch (RemoteException e) {
-
// Should never happen.
-
}
-
//低电关机
-
shutdownIfNoPowerLocked();
-
//电池温度过高关机
-
shutdownIfOverTempLocked();
-
-
if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
-
mBatteryProps.batteryHealth != mLastBatteryHealth ||
-
mBatteryProps.batteryPresent != mLastBatteryPresent ||
-
mBatteryProps.batteryLevel != mLastBatteryLevel ||
-
mPlugType != mLastPlugType ||
-
mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
-
mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
-
mInvalidCharger != mLastInvalidCharger)) {
-
//适配器插入状态有更改
-
if (mPlugType != mLastPlugType) {
-
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
-
// discharging -> charging
-
-
// There's no value in this data unless we've discharged at least once and the
-
// battery level has changed; so don't log until it does.
-
if (mDischargeStartTime !=
0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {
-
dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
-
logOutlier =
true;
-
EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
-
mDischargeStartLevel, mBatteryProps.batteryLevel);
-
// make sure we see a discharge event before logging again
-
mDischargeStartTime =
0;
-
}
-
}
else
if (mPlugType == BATTERY_PLUGGED_NONE) {
-
// charging -> discharging or we just powered up
-
mDischargeStartTime = SystemClock.elapsedRealtime();
-
mDischargeStartLevel = mBatteryProps.batteryLevel;
-
}
-
}
-
//电池状态更新
-
if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
-
mBatteryProps.batteryHealth != mLastBatteryHealth ||
-
mBatteryProps.batteryPresent != mLastBatteryPresent ||
-
mPlugType != mLastPlugType) {
-
EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
-
mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ?
1 :
0,
-
mPlugType, mBatteryProps.batteryTechnology);
-
}
-
if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
-
// Don't do this just from voltage or temperature changes, that is
-
// too noisy.
-
EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
-
mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
-
}
-
if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
-
mPlugType == BATTERY_PLUGGED_NONE) {
-
// We want to make sure we log discharge cycle outliers
-
// if the battery is about to die.
-
dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
-
logOutlier =
true;
-
}
-
-
if (!mBatteryLevelLow) {
-
// Should we now switch in to low battery mode?
-
if (mPlugType == BATTERY_PLUGGED_NONE
-
&& mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
-
mBatteryLevelLow =
true;
-
}
-
}
else {
-
// Should we now switch out of low battery mode?
-
if (mPlugType != BATTERY_PLUGGED_NONE) {
-
mBatteryLevelLow =
false;
-
}
else
if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
-
mBatteryLevelLow =
false;
-
}
else
if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
-
// If being forced, the previous state doesn't matter, we will just
-
// absolutely check to see if we are now above the warning level.
-
mBatteryLevelLow =
false;
-
}
-
}
-
//发送电池状态变换广播
-
sendIntentLocked();
-
-
// Separate broadcast is sent for power connected / not connected
-
// since the standard intent will not wake any applications and some
-
// applications may want to have smart behavior based on this.
-
if (mPlugType !=
0 && mLastPlugType ==
0) {
-
mHandler.post(new Runnable() {
-
@Override
-
public
void run() {
-
Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
-
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
-
}
-
});
-
}
-
else
if (mPlugType ==
0 && mLastPlugType !=
0) {
-
mHandler.post(new Runnable() {
-
@Override
-
public
void run() {
-
Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
-
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
-
}
-
});
-
}
-
//低电量电池事件通知
-
if (shouldSendBatteryLowLocked()) {
-
mSentLowBatteryBroadcast =
true;
-
mHandler.post(new Runnable() {
-
@Override
-
public
void run() {
-
Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
-
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
-
}
-
});
-
}
else
if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {
-
mSentLowBatteryBroadcast =
false;
-
mHandler.post(new Runnable() {
-
@Override
-
public
void run() {
-
Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
-
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
-
}
-
});
-
}
-
-
// Update the battery LED
-
mLed.updateLightsLocked();
-
-
// This needs to be done after sendIntent() so that we get the lastest battery stats.
-
if (logOutlier && dischargeDuration !=
0) {
-
logOutlierLocked(dischargeDuration);
-
}
-
-
mLastBatteryStatus = mBatteryProps.batteryStatus;
-
mLastBatteryHealth = mBatteryProps.batteryHealth;
-
mLastBatteryPresent = mBatteryProps.batteryPresent;
-
mLastBatteryLevel = mBatteryProps.batteryLevel;
-
mLastPlugType = mPlugType;
-
mLastBatteryVoltage = mBatteryProps.batteryVoltage;
-
mLastBatteryTemperature = mBatteryProps.batteryTemperature;
-
mLastBatteryLevelCritical = mBatteryLevelCritical;
-
mLastInvalidCharger = mInvalidCharger;
-
}
-
}
recovery模式不再分析。