Android Healthd电池服务分析

参考:https://blog.csdn.net/u012830148/article/details/80226498

healthd

healthd是安卓4.4之后提出来的,监听来自kernel的电池事件,并向上传递电池数据给framework层的BatteryService。BatteryService计算电池电量显示,剩余电量,电量级别以及绘制充电动画等信息,其代码位于/system/core/healthd。


   
   
  1. android/system/core/healthd/
  2. Android.mk BatteryMonitor.h BatteryPropertiesRegistrar.h healthd.cpp healthd_mode_android.cpp images
  3. BatteryMonitor.cpp BatteryPropertiesRegistrar.cpp healthd_board_default.cpp healthd.h healthd_mode_charger.cpp

下面一张图清晰的表示了Android电池系统框架




healthd服务入口:android/system/core/healthd/healthd.cpp  中main函数。


   
   
  1. int main( int argc, char **argv) {
  2. int ch;
  3. int ret;
  4. klog_set_level(KLOG_LEVEL);
  5. //healthd_mode_ops是一个关于充电状态的结构体变量,
  6. healthd_mode_ops = &android_ops; //开机充电时,指向android_ops
  7. if (!strcmp(basename(argv[ 0]), "charger")) {
  8. healthd_mode_ops = &charger_ops; //
  9. } else {
  10. while ((ch = getopt(argc, argv, "cr")) != -1) {
  11. switch (ch) {
  12. case 'c':
  13. healthd_mode_ops = &charger_ops; //关机状态下的充电
  14. break;
  15. case 'r':
  16. healthd_mode_ops = &recovery_ops; //recovery下的操作
  17. break;
  18. case '?':
  19. default:
  20. KLOG_ERROR(LOG_TAG, "Unrecognized healthd option: %c\n",
  21. optopt);
  22. exit( 1);
  23. }
  24. }
  25. }
  26. ret = healthd_init(); //healthed初始化
  27. if (ret) {
  28. KLOG_ERROR( "Initialization failed, exiting\n");
  29. exit( 2);
  30. }
  31. healthd_mainloop(); //主循环
  32. KLOG_ERROR( "Main loop terminated, exiting\n");
  33. return 3;
  34. }

在main函数中,首先根据传入的参数不同区分:开机充电、recovery、关机充电。这三种情况,然后指定不同的healthd_mode_ops回调函数。因此有必要贴出来这三个重要的回调。


   
   
  1. ///三个相关的ops
  2. static struct healthd_mode_ops android_ops = { 开机充电
  3. .init = healthd_mode_android_init,
  4. .preparetowait = healthd_mode_android_preparetowait,
  5. .heartbeat = healthd_mode_nop_heartbeat,
  6. .battery_update = healthd_mode_android_battery_update,
  7. };
  8. static struct healthd_mode_ops charger_ops = { 关机充电
  9. .init = healthd_mode_charger_init,
  10. .preparetowait = healthd_mode_charger_preparetowait,
  11. .heartbeat = healthd_mode_charger_heartbeat,
  12. .battery_update = healthd_mode_charger_battery_update,
  13. };
  14. static struct healthd_mode_ops recovery_ops = { recover相关的
  15. .init = healthd_mode_nop_init,
  16. .preparetowait = healthd_mode_nop_preparetowait,
  17. .heartbeat = healthd_mode_nop_heartbeat,
  18. .battery_update = healthd_mode_nop_battery_update,
  19. };

接着往下看healthd_init()


   
   
  1. static int healthd_init() {
  2. epollfd = epoll_create(MAX_EPOLL_EVENTS); //创建一个epoll变量
  3. if (epollfd == -1) {
  4. KLOG_ERROR(LOG_TAG,
  5. "epoll_create failed; errno=%d\n",
  6. errno);
  7. return -1;
  8. }
  9. //和板子级别的初始化,里面其实是一个空函数,什么也没做
  10. healthd_board_init(&healthd_config);
  11. //根据系统所处的模式,有三种情况的init,开机充电,关机充电,recovery
  12. healthd_mode_ops->init(&healthd_config);
  13. //wakealarm定时器初始化
  14. wakealarm_init();
  15. //uevent事件初始化,用以监听电池的uevent事件。
  16. uevent_init();
  17. //BatteryMonitor初始化。
  18. gBatteryMonitor = new BatteryMonitor(); //创建batteryMonitor对象
  19. gBatteryMonitor->init(&healthd_config); //初始化batteryMonitor,打开/sys/class/power_supply,
  20. //遍历该节点下的电池参数初始化healthd的config参数
  21. return 0;
  22. }

healthd_mode_ops->init(&healthd_config);根据main函数中传入的参数 有三种模式,Android,charger,recovery。


   
   
  1. android模式
  2. void healthd_mode_android_init( struct healthd_config* /*config*/) {
  3. ProcessState:: self()->setThreadPoolMaxThreadCount( 0); //获取线程池最大线程数
  4. IPCThreadState:: self()->disableBackgroundScheduling( true); //禁止后台调用
  5. IPCThreadState:: self()->setupPolling(&gBinderFd); //将gBinderFd加入到epoll中
  6. if (gBinderFd >= 0) {
  7. //将binder_event事件注册到gBinderfd文件节点用以监听Binder事件。
  8. if (healthd_register_event(gBinderFd, binder_event))
  9. KLOG_ERROR(LOG_TAG,
  10. "Register for binder events failed\n");
  11. }
  12. gBatteryPropertiesRegistrar = new BatteryPropertiesRegistrar();
  13. //将batteryProperties注册到ServiceManager中
  14. gBatteryPropertiesRegistrar->publish();
  15. }
charger模式就是关机充电模式,Android层只跑一个healthd服务用来显示充电动画和电量百分比。

   
   
  1. charger模式
  2. void healthd_mode_charger_init( struct healthd_config* config) //做充电动画相关的设置
  3. {
  4. int ret;
  5. struct charger *charger = &charger_state;
  6. int i;
  7. int epollfd;
  8. dump_last_kmsg();
  9. LOGW( "--------------- STARTING CHARGER MODE ---------------\n");
  10. ret = ev_init(input_callback, charger);
  11. if (!ret) {
  12. epollfd = ev_get_epollfd();
  13. healthd_register_event(epollfd, charger_event_handler);
  14. }
  15. ret = res_create_display_surface( "charger/battery_fail", &charger->surf_unknown);
  16. if (ret < 0) {
  17. LOGE( "Cannot load battery_fail image\n");
  18. charger->surf_unknown = NULL;
  19. }
  20. charger->batt_anim = &battery_animation; //指定充电动画相关的属性
  21. gr_surface* scale_frames;
  22. int scale_count;
  23. ret = res_create_multi_display_surface( "charger/battery_scale", &scale_count, &scale_frames); //读取充电动画资源
  24. if (ret < 0) {
  25. LOGE( "Cannot load battery_scale image\n");
  26. charger->batt_anim->num_frames = 0;
  27. charger->batt_anim->num_cycles = 1;
  28. } else if (scale_count != charger->batt_anim->num_frames) {
  29. LOGE( "battery_scale image has unexpected frame count (%d, expected %d)\n",
  30. scale_count, charger->batt_anim->num_frames);
  31. charger->batt_anim->num_frames = 0;
  32. charger->batt_anim->num_cycles = 1;
  33. } else {
  34. for (i = 0; i < charger->batt_anim->num_frames; i++) { //读取资源成功,存放起来
  35. charger->batt_anim->frames[i].surface = scale_frames[i];
  36. }
  37. }
  38. ev_sync_key_state(set_key_callback, charger);
  39. charger->next_screen_transition = -1;
  40. charger->next_key_check = -1;
  41. charger->next_pwr_check = -1;
  42. healthd_config = config;
  43. }

   
   
  1. //接着到wakealarm_init
  2. static void wakealarm_init( void) {
  3. //创建一个月wakealarm对应的定时器描述符
  4. wakealarm_fd = timerfd_create( CLOCK_BOOTTIME_ALARM, TFD_NONBLOCK);
  5. if (wakealarm_fd == -1) {
  6. KLOG_ERROR(LOG_TAG, "wakealarm_init: timerfd_create failed\n");
  7. return;
  8. }
  9. //将wakealarm事件注册到wakealarm_fd文件节点上以监听wakealarm事件。
  10. if (healthd_register_event(wakealarm_fd, wakealarm_event))
  11. KLOG_ERROR(LOG_TAG,
  12. "Registration of wakealarm event failed\n");
  13. //设置alarm唤醒间隔
  14. wakealarm_set_interval(healthd_config.periodic_chores_interval_fast);
  15. }

   
   
  1. static void uevent_init( void) {
  2. //创建并打开一个socket文件描述符uevent_fd
  3. uevent_fd = uevent_open_socket( 64* 1024, true);
  4. if (uevent_fd < 0) {
  5. KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
  6. return;
  7. }
  8. //将其设置为非阻塞模式
  9. fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
  10. //将其注册到healthed_init创建的描述符集合里
  11. if (healthd_register_event(uevent_fd, uevent_event))
  12. KLOG_ERROR(LOG_TAG,
  13. "register for uevent events failed\n");
  14. }

   
   
  1. static void healthd_mainloop( void) {
  2. while ( 1) {
  3. struct epoll_event events[eventct];
  4. int nevents;
  5. int timeout = awake_poll_interval;
  6. int mode_timeout;
  7. //获取等待事件的超时时间,events是从epollfd上轮询的中监听得到的事件数目。
  8. mode_timeout = healthd_mode_ops->preparetowait();
  9. if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout))
  10. timeout = mode_timeout;
  11. //接收event事件
  12. nevents = epoll_wait(epollfd, events, eventct, timeout);
  13. if (nevents == -1) {
  14. if (errno == EINTR)
  15. continue;
  16. KLOG_ERROR(LOG_TAG, "healthd_mainloop: epoll_wait failed\n");
  17. break;
  18. }
  19. //遍历处理每一个事件
  20. for ( int n = 0; n < nevents; ++n) {
  21. if (events[n].data.ptr)
  22. (*( void (*)( int))events[n].data.ptr)(events[n].events);
  23. }
  24. //如果有事件发生,更新电池状态
  25. if (!nevents)
  26. periodic_chores(); //更新电池状态信息
  27. healthd_battery_update();
  28. healthd_mode_ops->heartbeat(); //如果是在关机充电模式的话去绘制充电动画。
  29. //开机充电的话则不做任何事情。
  30. }
  31. return;
  32. }

如果是关机充电模式,则healthd_mode_ops->heartbeat(); 执行的是healthd_mode_charger_heartbeat()函数


   
   
  1. void healthd_mode_charger_heartbeat()
  2. {
  3. struct charger *charger = &charger_state;
  4. int64_t now = curr_time_ms();
  5. int ret;
  6. handle_input_state(charger, now); //处理按键相关的事情,长按开机
  7. handle_power_supply_state(charger, now);
  8. /* do screen update last in case any of the above want to start
  9. * screen transitions (animations, etc)
  10. */
  11. update_screen_state(charger, now); //绘制充电动画
  12. }

   
   
  1. frameworks/base/services/core/java/com/android/server/BatteryService.java
  2. //将电池监听注册到底层
  3. public void onStart() {
  4. IBinder b = ServiceManager.getService( "batteryproperties");
  5. final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
  6. IBatteryPropertiesRegistrar.Stub.asInterface(b);
  7. try {
  8. //注册电池监听,当底层电池电量发生变化调用此监听,并调用update。
  9. batteryPropertiesRegistrar.registerListener(new BatteryListener());
  10. } catch (RemoteException e) {
  11. // Should never happen.
  12. }
  13. publishBinderService( "battery", new BinderService());
  14. publishLocalService(BatteryManagerInternal.class, new LocalService());
  15. }
  16. //当底层有信息时,会调用update更新BatteryService中相关值。
  17. private void update(BatteryProperties props) {
  18. synchronized (mLock) {
  19. if (!mUpdatesStopped) {
  20. mBatteryProps = props;
  21. // Process the new values.
  22. processValuesLocked( false);
  23. } else {
  24. mLastBatteryProps.set(props);
  25. }
  26. }
  27. }

   
   
  1. private void processValuesLocked(boolean force) {
  2. boolean logOutlier = false;
  3. long dischargeDuration = 0;
  4. //获取电池电量是否低于critical界限。
  5. mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
  6. //获取电池充电状态,AC,USB,无线,以及什么都没接。
  7. if (mBatteryProps.chargerAcOnline) {
  8. mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
  9. } else if (mBatteryProps.chargerUsbOnline) {
  10. mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
  11. } else if (mBatteryProps.chargerWirelessOnline) {
  12. mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
  13. } else {
  14. mPlugType = BATTERY_PLUGGED_NONE;
  15. }
  16. if (DEBUG) {
  17. Slog.d(TAG, "Processing new values: "
  18. + "chargerAcOnline=" + mBatteryProps.chargerAcOnline
  19. + ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
  20. + ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
  21. + ", batteryStatus=" + mBatteryProps.batteryStatus
  22. + ", batteryHealth=" + mBatteryProps.batteryHealth
  23. + ", batteryPresent=" + mBatteryProps.batteryPresent
  24. + ", batteryLevel=" + mBatteryProps.batteryLevel
  25. + ", batteryTechnology=" + mBatteryProps.batteryTechnology
  26. + ", batteryVoltage=" + mBatteryProps.batteryVoltage
  27. + ", batteryTemperature=" + mBatteryProps.batteryTemperature
  28. + ", mBatteryLevelCritical=" + mBatteryLevelCritical
  29. + ", mPlugType=" + mPlugType);
  30. }
  31. // Let the battery stats keep track of the current level.
  32. try {
  33. mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
  34. mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
  35. mBatteryProps.batteryVoltage);
  36. } catch (RemoteException e) {
  37. // Should never happen.
  38. }
  39. //低电关机
  40. shutdownIfNoPowerLocked();
  41. //电池温度过高关机
  42. shutdownIfOverTempLocked();
  43. if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
  44. mBatteryProps.batteryHealth != mLastBatteryHealth ||
  45. mBatteryProps.batteryPresent != mLastBatteryPresent ||
  46. mBatteryProps.batteryLevel != mLastBatteryLevel ||
  47. mPlugType != mLastPlugType ||
  48. mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
  49. mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
  50. mInvalidCharger != mLastInvalidCharger)) {
  51. //适配器插入状态有更改
  52. if (mPlugType != mLastPlugType) {
  53. if (mLastPlugType == BATTERY_PLUGGED_NONE) {
  54. // discharging -> charging
  55. // There's no value in this data unless we've discharged at least once and the
  56. // battery level has changed; so don't log until it does.
  57. if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {
  58. dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
  59. logOutlier = true;
  60. EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
  61. mDischargeStartLevel, mBatteryProps.batteryLevel);
  62. // make sure we see a discharge event before logging again
  63. mDischargeStartTime = 0;
  64. }
  65. } else if (mPlugType == BATTERY_PLUGGED_NONE) {
  66. // charging -> discharging or we just powered up
  67. mDischargeStartTime = SystemClock.elapsedRealtime();
  68. mDischargeStartLevel = mBatteryProps.batteryLevel;
  69. }
  70. }
  71. //电池状态更新
  72. if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
  73. mBatteryProps.batteryHealth != mLastBatteryHealth ||
  74. mBatteryProps.batteryPresent != mLastBatteryPresent ||
  75. mPlugType != mLastPlugType) {
  76. EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
  77. mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0,
  78. mPlugType, mBatteryProps.batteryTechnology);
  79. }
  80. if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
  81. // Don't do this just from voltage or temperature changes, that is
  82. // too noisy.
  83. EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
  84. mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
  85. }
  86. if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
  87. mPlugType == BATTERY_PLUGGED_NONE) {
  88. // We want to make sure we log discharge cycle outliers
  89. // if the battery is about to die.
  90. dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
  91. logOutlier = true;
  92. }
  93. if (!mBatteryLevelLow) {
  94. // Should we now switch in to low battery mode?
  95. if (mPlugType == BATTERY_PLUGGED_NONE
  96. && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
  97. mBatteryLevelLow = true;
  98. }
  99. } else {
  100. // Should we now switch out of low battery mode?
  101. if (mPlugType != BATTERY_PLUGGED_NONE) {
  102. mBatteryLevelLow = false;
  103. } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
  104. mBatteryLevelLow = false;
  105. } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
  106. // If being forced, the previous state doesn't matter, we will just
  107. // absolutely check to see if we are now above the warning level.
  108. mBatteryLevelLow = false;
  109. }
  110. }
  111. //发送电池状态变换广播
  112. sendIntentLocked();
  113. // Separate broadcast is sent for power connected / not connected
  114. // since the standard intent will not wake any applications and some
  115. // applications may want to have smart behavior based on this.
  116. if (mPlugType != 0 && mLastPlugType == 0) {
  117. mHandler.post(new Runnable() {
  118. @Override
  119. public void run() {
  120. Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
  121. statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  122. mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
  123. }
  124. });
  125. }
  126. else if (mPlugType == 0 && mLastPlugType != 0) {
  127. mHandler.post(new Runnable() {
  128. @Override
  129. public void run() {
  130. Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
  131. statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  132. mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
  133. }
  134. });
  135. }
  136. //低电量电池事件通知
  137. if (shouldSendBatteryLowLocked()) {
  138. mSentLowBatteryBroadcast = true;
  139. mHandler.post(new Runnable() {
  140. @Override
  141. public void run() {
  142. Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
  143. statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  144. mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
  145. }
  146. });
  147. } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {
  148. mSentLowBatteryBroadcast = false;
  149. mHandler.post(new Runnable() {
  150. @Override
  151. public void run() {
  152. Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
  153. statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  154. mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
  155. }
  156. });
  157. }
  158. // Update the battery LED
  159. mLed.updateLightsLocked();
  160. // This needs to be done after sendIntent() so that we get the lastest battery stats.
  161. if (logOutlier && dischargeDuration != 0) {
  162. logOutlierLocked(dischargeDuration);
  163. }
  164. mLastBatteryStatus = mBatteryProps.batteryStatus;
  165. mLastBatteryHealth = mBatteryProps.batteryHealth;
  166. mLastBatteryPresent = mBatteryProps.batteryPresent;
  167. mLastBatteryLevel = mBatteryProps.batteryLevel;
  168. mLastPlugType = mPlugType;
  169. mLastBatteryVoltage = mBatteryProps.batteryVoltage;
  170. mLastBatteryTemperature = mBatteryProps.batteryTemperature;
  171. mLastBatteryLevelCritical = mBatteryLevelCritical;
  172. mLastInvalidCharger = mInvalidCharger;
  173. }
  174. }

recovery模式不再分析。













  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值