深入解析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; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。