深入解析android5.1 healthd
healthd主要是读取电池节点的信息,传给BatteryService。或者在关机充电等使用。注意healthd中使用的是kernel的log。
下面先从main函数分析
intmain(intargc,char**argv){
intch;
intret;
klog_set_level(KLOG_LEVEL);
healthd_mode_ops=&android_ops;
if(!strcmp(basename(argv[0]),"charger")){//解析输入参数如果是charger的使用charger_ops,这里就不做介绍
healthd_mode_ops=&charger_ops;
}else{
while((ch=getopt(argc,argv,"cr"))!=-1){//分析输入命令,各个命令对应不同的charger_ops
switch(ch){
case'c':
healthd_mode_ops=&charger_ops;
break;
case'r':
healthd_mode_ops=&recovery_ops;
break;
case'?':
default:
KLOG_ERROR(LOG_TAG,"Unrecognizedhealthdoption:%c\n",
optopt);
exit(1);
}
}
}
ret=healthd_init();//healthd做初始化
if(ret){
KLOG_ERROR("Initializationfailed,exiting\n");
exit(2);
}
healthd_mainloop();//主函数
KLOG_ERROR("Mainloopterminated,exiting\n");
return3;
}
如果是正常开机,不走关机充电等,healthd_mode_ops=&android_ops;而这里面具体的函数在后面进行详细的介绍。
staticstructhealthd_mode_opsandroid_ops={
.init=healthd_mode_android_init,
.preparetowait=healthd_mode_android_preparetowait,
.heartbeat=healthd_mode_nop_heartbeat,
.battery_update=healthd_mode_android_battery_update,
};
下面分析下healthd_init函数,heathd使用了epoll进行IO复用。
staticinthealthd_init(){
epollfd=epoll_create(MAX_EPOLL_EVENTS);
if(epollfd==-1){
KLOG_ERROR(LOG_TAG,
"epoll_createfailed;errno=%d\n",
errno);
return-1;
}
healthd_board_init(&healthd_config);
healthd_mode_ops->init(&healthd_config);
wakealarm_init();
uevent_init();
gBatteryMonitor=newBatteryMonitor();
gBatteryMonitor->init(&healthd_config);
return0;
}
这里的healthd_mode_ops->init的函数是android_ops的healthd_mode_android_init函数,这里主要是将binder通信的fd也加入epoll,而不像普通binder进程最后使用IPCThreadState::self()->joinThreadPool。这样所有的fd全在epoll管理,只用了一个线程
inthealthd_mode_android_preparetowait(void){
IPCThreadState::self()->flushCommands();
return-1;
}
staticvoidbinder_event(uint32_t/*epevents*/){
IPCThreadState::self()->handlePolledCommands();
}
voidhealthd_mode_android_init(structhealthd_config*/*config*/){
ProcessState::self()->setThreadPoolMaxThreadCount(0);
IPCThreadState::self()->disableBackgroundScheduling(true);
IPCThreadState::self()->setupPolling(&gBinderFd);
if(gBinderFd>=0){
if(healthd_register_event(gBinderFd,binder_event))
KLOG_ERROR(LOG_TAG,
"Registerforbindereventsfailed\n");
}
gBatteryPropertiesRegistrar=newBatteryPropertiesRegistrar();
gBatteryPropertiesRegistrar->publish();
}
gBatteryPropertiesRegistrar->publish将"batteryproperties"这个Service加入到ServiceManager中
voidBatteryPropertiesRegistrar::publish(){
defaultServiceManager()->addService(String16("batteryproperties"),this);
}
接下来再来看下wakealarm_init
staticvoidwakealarm_init(void){
wakealarm_fd=timerfd_create(CLOCK_BOOTTIME_ALARM,TFD_NONBLOCK);
if(wakealarm_fd==-1){
KLOG_ERROR(LOG_TAG,"wakealarm_init:timerfd_createfailed\n");
return;
}
if(healthd_register_event(wakealarm_fd,wakealarm_event))
KLOG_ERROR(LOG_TAG,
"Registrationofwakealarmeventfailed\n");
wakealarm_set_interval(healthd_config.periodic_chores_interval_fast);
}
wakealarm_init设置alarm唤醒的interval,再来看下时间处理函数
staticvoidwakealarm_event(uint32_t/*epevents*/){
unsignedlonglongwakeups;
if(read(wakealarm_fd,&wakeups,sizeof(wakeups))==-1){//出错结束
KLOG_ERROR(LOG_TAG,"wakealarm_event:readwakealarmfdfailed\n");
return;
}
KLOG_ERROR(LOG_TAG,"wakealarm_event\n");
periodic_chores();
}
staticvoidperiodic_chores(){
healthd_battery_update();
}
voidhealthd_battery_update(void){
//Fastwakeintervalwhenoncharger(watchforoverheat);
//slowwakeintervalwhenonbattery(watchfordrainedbattery).
KLOG_ERROR(LOG_TAG,"healthd_battery_updateenter\n");
intnew_wake_interval=gBatteryMonitor->update()?//调用主要的update函数,根据返回值,如果当前在充电返回true
healthd_config.periodic_chores_interval_fast://时间设置1分钟
healthd_config.periodic_chores_interval_slow;
KLOG_ERROR(LOG_TAG,"healthd_battery_updateafter\n");
if(new_wake_interval!=wakealarm_wake_interval)
wakealarm_set_interval(new_wake_interval);
//Duringawakeperiodspollatfastrate.Ifwakealarmissetatfast
//ratethenjustusethealarm;ifwakealarmissetatslowratethen
//pollatfastratewhileawakeandletalarmwakeupatslowratewhen
//asleep.
if(healthd_config.periodic_chores_interval_fast==-1)
awake_poll_interval=-1;
else
awake_poll_interval=
new_wake_interval==healthd_config.periodic_chores_interval_fast?//当前时间是一分钟,epoll为永远阻塞,否则为1分钟
-1:healthd_config.periodic_chores_interval_fast*1000;
}
接下来再来看看uEvent的,
staticvoiduevent_init(void){
uevent_fd=uevent_open_socket(64*1024,true);
if(uevent_fd<0){
KLOG_ERROR(LOG_TAG,"uevent_init:uevent_open_socketfailed\n");
return;
}
fcntl(uevent_fd,F_SETFL,O_NONBLOCK);
if(healthd_register_event(uevent_fd,uevent_event))
KLOG_ERROR(LOG_TAG,
"registerforueventeventsfailed\n");
}
看看uevent_event的处理函数,获取uevent后主要判断是否是电源系统的,如果是调用healthd_battery_update函数
staticvoiduevent_event(uint32_t/*epevents*/){
charmsg[UEVENT_MSG_LEN+2];
char*cp;
intn;
n=uevent_kernel_multicast_recv(uevent_fd,msg,UEVENT_MSG_LEN);
if(n<=0)
return;
if(n>=UEVENT_MSG_LEN)/*overflow--discard*/
return;
msg[n]='\0';
msg[n+1]='\0';
cp=msg;
KLOG_ERROR(LOG_TAG,"uevent_event\n");
while(*cp){
if(!strcmp(cp,"SUBSYSTEM="POWER_SUPPLY_SUBSYSTEM)){//是这个子系统的调用healthd_battery_update函数
healthd_battery_update();
break;
}
/*advancetoafterthenext\0*/
while(*cp++)
;
}
}
下面分析下healthd_mainloop这个主函数,主函数主要是epoll函数监听3个fd,有事件就处理。
staticvoidhealthd_mainloop(void){
while(1){
structepoll_eventevents[eventct];
intnevents;
inttimeout=awake_poll_interval;
intmode_timeout;
mode_timeout=healthd_mode_ops->preparetowait();
if(timeout<0||(mode_timeout>0&&mode_timeoutheartbeat();
}
return;
}
init函数主要将healthd_config对象传入,并且将里面的成员的一些地址信息去初始化保存起来。主要是保存一些地址信息,以及充电方式。
voidBatteryMonitor::init(structhealthd_config*hc){
String8path;
charpval[PROPERTY_VALUE_MAX];
mHealthdConfig=hc;//将外面传进来的heathdconfig的指针赋给成员变量
DIR*dir=opendir(POWER_SUPPLY_SYSFS_PATH);//打开地址/sys/class/power_supply
if(dir==NULL){
KLOG_ERROR(LOG_TAG,"Couldnotopen%s\n",POWER_SUPPLY_SYSFS_PATH);
}else{
structdirent*entry;
while((entry=readdir(dir))){
constchar*name=entry->d_name;
if(!strcmp(name,".")||!strcmp(name,".."))
continue;
charbuf[20];
//Lookfor"type"fileineachsubdirectory
path.clear();
path.appendFormat("%s/%s/type",POWER_SUPPLY_SYSFS_PATH,name);
switch(readPowerSupplyType(path)){//读取各个目录下type的值,比如/sys/class/power_supply/battery下type的值为Battery,在readPowerSupplyType读取并且转化为ANDROID_POWER_SUPPLY_TYPE_BATTERY
caseANDROID_POWER_SUPPLY_TYPE_AC:
if(mHealthdConfig->acChargeHeathPath.isEmpty()){
path.clear();
path.appendFormat("%s/%s/health",POWER_SUPPLY_SYSFS_PATH,
name);
if(access(path,R_OK)==0)
mHealthdConfig->acChargeHeathPath=path;//配置路径
}
path.clear();
path.appendFormat("%s/%s/online",POWER_SUPPLY_SYSFS_PATH,name);
if(access(path.string(),R_OK)==0)
mChargerNames.add(String8(name));//chargername就是当前目录名字:ac
break;
caseANDROID_POWER_SUPPLY_TYPE_USB://usb类似ac
if(mHealthdConfig->usbChargeHeathPath.isEmpty()){
path.clear();
path.appendFormat("%s/%s/health",POWER_SUPPLY_SYSFS_PATH,
name);
if(access(path,R_OK)==0)
mHealthdConfig->usbChargeHeathPath=path;
}
path.clear();
path.appendFormat("%s/%s/online",POWER_SUPPLY_SYSFS_PATH,name);
if(access(path.string(),R_OK)==0)
mChargerNames.add(String8(name));
break;
caseANDROID_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));
break;
caseANDROID_POWER_SUPPLY_TYPE_BATTERY://battery
mBatteryDevicePresent=true;
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;
}
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;
}
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;
}
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;
}
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;
}else{
path.clear();
path.appendFormat("%s/%s/batt_vol",
POWER_SUPPLY_SYSFS_PATH,name);
if(access(path,R_OK)==0)
mHealthdConfig->batteryVoltagePath=path;
}
}
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;
}
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;
}
if(mHealthdConfig->batteryChargeCounterPath.isEmpty()){
path.clear();
path.appendFormat("%s/%s/charge_counter",
POWER_SUPPLY_SYSFS_PATH,name);
if(access(path,R_OK)==0)
mHealthdConfig->batteryChargeCounterPath=path;
}
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;
}else{
path.clear();
path.appendFormat("%s/%s/batt_temp",
POWER_SUPPLY_SYSFS_PATH,name);
if(access(path,R_OK)==0)
mHealthdConfig->batteryTemperaturePath=path;
}
}
if(mHealthdConfig->batteryTechnologyPath.isEmpty()){
path.clear();
path.appendFormat("%s/%s/technology",
POWER_SUPPLY_SYSFS_PATH,name);
if(access(path,R_OK)==0)
mHealthdConfig->batteryTechnologyPath=path;
}
break;
caseANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
break;
}
}
closedir(dir);
}
if(!mChargerNames.size())
KLOG_ERROR(LOG_TAG,"Nochargersuppliesfound\n");
if(!mBatteryDevicePresent){//主要由battery该成员变量就为true
KLOG_WARNING(LOG_TAG,"Nobatterydevicesfound\n");
hc->periodic_chores_interval_fast=-1;
hc->periodic_chores_interval_slow=-1;
}else{
if(mHealthdConfig->batteryStatusPath.isEmpty())
KLOG_WARNING(LOG_TAG,"BatteryStatusPathnotfound\n");
。。。。。。。。。。。。。//这里都是一些警告
}
if(property_get("ro.boot.fake_battery",pval,NULL)>0
&&strtol(pval,NULL,10)!=0){
mBatteryFixedCapacity=FAKE_BATTERY_CAPACITY;
mBatteryFixedTemperature=FAKE_BATTERY_TEMPERATURE;
}
}
下面就是update函数,将数据封装在BatteryProperties中,并且通过healthd_mode_ops->battery_update把BatteryProperties发给上层。
boolBatteryMonitor::update(void){
boollogthis;
props.chargerAcOnline=false;
props.chargerUsbOnline=false;
props.chargerWirelessOnline=false;
props.batteryStatus=BATTERY_STATUS_UNKNOWN;
props.batteryHealth=BATTERY_HEALTH_UNKNOWN;
//都是从之前配置的mHealthd中取地址,读取节点信息,保存到props成员变量中
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;
props.batteryTemperature=mBatteryFixedTemperature?
mBatteryFixedTemperature:
getIntField(mHealthdConfig->batteryTemperaturePath);
constintSIZE=128;
charbuf[SIZE];
String8btech;
if(readFromFile(mHealthdConfig->batteryStatusPath,buf,SIZE)>0)
props.batteryStatus=getBatteryStatus(buf);
if(readFromFile(mHealthdConfig->batteryHealthPath,buf,SIZE)>0)
props.batteryHealth=getBatteryHealth(buf);
if(readFromFile(mHealthdConfig->batteryTechnologyPath,buf,SIZE)>0)
props.batteryTechnology=String8(buf);
if(readFromFile(mHealthdConfig->acChargeHeathPath,buf,SIZE)>0)
props.acChargeHeath=String8(buf);
if(readFromFile(mHealthdConfig->usbChargeHeathPath,buf,SIZE)>0)
props.usbChargeHeath=String8(buf);
unsignedinti;
for(i=0;i0){
if(buf[0]!='0'){//读取online里面的内容,如果当前在usb线上充电,那么usb下online里面的内容为1
path.clear();
path.appendFormat("%s/%s/type",POWER_SUPPLY_SYSFS_PATH,
mChargerNames[i].string());//这里看看是哪个type的
switch(readPowerSupplyType(path)){
caseANDROID_POWER_SUPPLY_TYPE_AC:
props.chargerAcOnline=true;
break;
caseANDROID_POWER_SUPPLY_TYPE_USB://将其值赋成true
props.chargerUsbOnline=true;
break;
caseANDROID_POWER_SUPPLY_TYPE_WIRELESS:
props.chargerWirelessOnline=true;
break;
default:
KLOG_WARNING(LOG_TAG,"%s:Unknownpowersupplytype\n",
mChargerNames[i].string());
}
}
}
}
logthis=!healthd_board_battery_update(&props);
if(logthis){
chardmesgline[256];
if(props.batteryPresent){
snprintf(dmesgline,sizeof(dmesgline),
"batteryl=%dv=%dt=%s%d.%dh=%dst=%d",
props.batteryLevel,props.batteryVoltage,
props.batteryTemperature<0?"-":"",
abs(props.batteryTemperature/10),
abs(props.batteryTemperature%10),props.batteryHealth,
props.batteryStatus);
if(!mHealthdConfig->batteryCurrentNowPath.isEmpty()){
intc=getIntField(mHealthdConfig->batteryCurrentNowPath);
charb[20];
snprintf(b,sizeof(b),"c=%d",c/1000);
strlcat(dmesgline,b,sizeof(dmesgline));
}
}else{
snprintf(dmesgline,sizeof(dmesgline),
"batterynone");
}
KLOG_WARNING(LOG_TAG,"%schg=%s%s%s\n",dmesgline,
props.chargerAcOnline?"a":"",
props.chargerUsbOnline?"u":"",
props.chargerWirelessOnline?"w":"");
}
healthd_mode_ops->battery_update(&props);//将数据传到上层的BatteryService
returnprops.chargerAcOnline|props.chargerUsbOnline|//返回当前是否属于充电
props.chargerWirelessOnline;
}
接下来看看healthd_mode_ops->battery_update是怎么把数据传到上层的
voidhealthd_mode_android_battery_update(
structandroid::BatteryProperties*props){
if(gBatteryPropertiesRegistrar!=NULL)
gBatteryPropertiesRegistrar->notifyListeners(*props);
return;
}
上层会通过binder通信,注册一个回调到BatteryPropertiesRegistrar
voidBatteryPropertiesRegistrar::registerListener(constsp&listener){ { if(listener==NULL) return; Mutex::Autolock_l(mRegistrationLock); //checkwhetherthisisaduplicate for(size_ti=0;i asBinder()==listener->asBinder()){ return; } } mListeners.add(listener); listener->asBinder()->linkToDeath(this); } healthd_battery_update(); }
而update函数就是调用了notifyListeners遍历各个listener传到上层BatteryService
voidBatteryPropertiesRegistrar::notifyListeners(structBatteryPropertiesprops){
Mutex::Autolock_l(mRegistrationLock);
for(size_ti=0;ibatteryPropertiesChanged(props);
}
}
再来看看BatteryService中,在onStart中通过ServiceManager,和batteryproperties这个Service通信,将BatteryListener这个listenter注册到batteryproperties中去
@Override
publicvoidonStart(){
IBinderb=ServiceManager.getService("batteryproperties");
finalIBatteryPropertiesRegistrarbatteryPropertiesRegistrar=
IBatteryPropertiesRegistrar.Stub.asInterface(b);
try{
batteryPropertiesRegistrar.registerListener(newBatteryListener());
}catch(RemoteExceptione){
//Shouldneverhappen.
}
publishBinderService("battery",newBinderService());
publishLocalService(BatteryManagerInternal.class,newLocalService());
}
再来看看BatteryListener的batteryPropertiesChanged接口,当下面调这个接口,就会调用BatteryService的update函数,然后就是BatteryService的一些主要流程就不分析了。
privatefinalclassBatteryListenerextendsIBatteryPropertiesListener.Stub{
@Override
publicvoidbatteryPropertiesChanged(BatteryPropertiesprops){
finallongidentity=Binder.clearCallingIdentity();
try{
BatteryService.this.update(props);
}finally{
Binder.restoreCallingIdentity(identity);
}
}
}
BatteryService接受healthd的数据都是被动的,healthd穿过来的。有没有主动去healthd查询的。
在BatteryManager中就有主动去healthd查询的,代码如下
privatelongqueryProperty(intid){
longret;
if(mBatteryPropertiesRegistrar==null){
IBinderb=ServiceManager.getService("batteryproperties");//获取batterypropertiesService
mBatteryPropertiesRegistrar=
IBatteryPropertiesRegistrar.Stub.asInterface(b);//接口转化下
if(mBatteryPropertiesRegistrar==null)
returnLong.MIN_VALUE;
}
try{
BatteryPropertyprop=newBatteryProperty();
if(mBatteryPropertiesRegistrar.getProperty(id,prop)==0)//prop是输出
ret=prop.getLong();
else
ret=Long.MIN_VALUE;
}catch(RemoteExceptione){
ret=Long.MIN_VALUE;
}
returnret;
}
再到healthd看看对应的接口
status_tBatteryPropertiesRegistrar::getProperty(intid,structBatteryProperty*val){
returnhealthd_get_property(id,val);
}
status_thealthd_get_property(intid,structBatteryProperty*val){
returngBatteryMonitor->getProperty(id,val);
}
java的BatteryProperty对象对应到这边是指针
status_tBatteryMonitor::getProperty(intid,structBatteryProperty*val){
status_tret=BAD_VALUE;
val->valueInt64=LONG_MIN;
switch(id){
caseBATTERY_PROP_CHARGE_COUNTER://根据不同ID,返回不同值
if(!mHealthdConfig->batteryChargeCounterPath.isEmpty()){
val->valueInt64=
getIntField(mHealthdConfig->batteryChargeCounterPath);
ret=NO_ERROR;
}else{
ret=NAME_NOT_FOUND;
}
break;
caseBATTERY_PROP_CURRENT_NOW:
if(!mHealthdConfig->batteryCurrentNowPath.isEmpty()){
val->valueInt64=
getIntField(mHealthdConfig->batteryCurrentNowPath);
ret=NO_ERROR;
}else{
ret=NAME_NOT_FOUND;
}
break;
caseBATTERY_PROP_CURRENT_AVG:
if(!mHealthdConfig->batteryCurrentAvgPath.isEmpty()){
val->valueInt64=
getIntField(mHealthdConfig->batteryCurrentAvgPath);
ret=NO_ERROR;
}else{
ret=NAME_NOT_FOUND;
}
break;
caseBATTERY_PROP_CAPACITY:
if(!mHealthdConfig->batteryCapacityPath.isEmpty()){
val->valueInt64=
getIntField(mHealthdConfig->batteryCapacityPath);
ret=NO_ERROR;
}else{
ret=NAME_NOT_FOUND;
}
break;
caseBATTERY_PROP_ENERGY_COUNTER:
if(mHealthdConfig->energyCounter){
ret=mHealthdConfig->energyCounter(&val->valueInt64);
}else{
ret=NAME_NOT_FOUND;
}
break;
default:
break;
}
returnret;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。