
基于AndroID 11 BatteryService 分析
BatteryService 介绍BatteryService是电池管理的重要服务,该服务继承SystemService,主要用于管理 电池的充电状态,充电百分比等。
初始化数据
mHandler = new Handler(true /*async*/); //Led封装了lightsManager,不同电量下led灯的颜色就由它来控制 mLed = new Led(context, getLocalService(lightsManager.class)); mBatteryStats = BatteryStatsService.getService(); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); //读取临界值电量配置 mCriticalbatterylevel = mContext.getResources().getInteger( com.androID.internal.R.integer.config_criticalBatteryWarningLevel); //低电警告的电量 mLowBatteryWarningLevel = mContext.getResources().getInteger( com.androID.internal.R.integer.config_lowBatteryWarningLevel); //关闭低电警告的电量 mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger( com.androID.internal.R.integer.config_lowBatteryCloseWarningBump); //关闭电池的温度 mShutdownBatteryTemperature = mContext.getResources().getInteger( com.androID.internal.R.integer.config_shutdownBatteryTemperature);220 // watch for invalID charger messages if the invalID_charger switch exists221 if (new file("/sys/devices/virtual/switch/invalID_charger/state").exists()) {222 UEventObserver invalIDChargerObserver = new UEventObserver() {223 @OverrIDe224 public voID onUEvent(UEvent event) {225 final int invalIDCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;226 synchronized (mlock) {227 if (mInvalIDCharger != invalIDCharger) {228 mInvalIDCharger = invalIDCharger;229 }230 }231 }232 };233 invalIDChargerObserver.startObserving(234 "DEVPATH=/devices/virtual/switch/invalID_charger");
238 @OverrIDe239 public voID onStart() {240 registerHealthCallback();//注册接口241242 mBinderService = new BinderService();//将自己注册到service manager进程中243 publishBinderService("battery", mBinderService);244 mBatteryPropertIEsRegistrar = new BatteryPropertIEsRegistrar();//将自己注册到service manager进程中245 publishBinderService("batterypropertIEs", mBatteryPropertIEsRegistrar);/以后BatteryManagerInternal接口类型的对象,只能有BatteryService的内部类LocalService一个246 publishLocalService(BatteryManagerInternal.class, new LocalService());247 }注册了底层电量变换的回调方法,最终调用BatteryService的update方法更新电池信息
271 private voID registerHealthCallback() {272 traceBegin("HealthInitWrapper");273 mHealthServiceWrapper = new HealthServiceWrapper();274 mHealthHalCallback = new HealthHalCallback();275 // IHealth is lazily retrIEved.276 try {277 mHealthServiceWrapper.init(mHealthHalCallback,278 new HealthServiceWrapper.IServiceManagersupplier() {},279 new HealthServiceWrapper.IHealthsupplier() {});280 } catch (remoteexception ex) {281 Slog.e(TAG, "health: cannot register callback. (remoteexception)");282 throw ex.rethrowFromSystemServer();283 } catch (NoSuchElementException ex) {284 Slog.e(TAG, "health: cannot register callback. (no supported health HAL service)");285 throw ex;286 } finally {287 traceEnd();288 }289290 traceBegin("HealthInitWaitUpdate");291 // init register for new service notifications, and IServiceManager should return the292 // existing service in a near future. Wait for this.update() to instantiate293 // the initial mHealthInfo.294 long beforeWait = SystemClock.uptimeMillis();295 synchronized (mlock) {296 while (mHealthInfo == null) {297 Slog.i(TAG, "health: Waited " + (SystemClock.uptimeMillis() - beforeWait) +298 "ms for callbacks. Waiting another " + HEALTH_HAL_WAIT_MS + " ms...");299 try {300 mlock.wait(HEALTH_HAL_WAIT_MS);301 } catch (InterruptedException ex) {302 Slog.i(TAG, "health: InterruptedException when waiting for update. "303 + " Continuing...");304 }305 }306 }307308 Slog.i(TAG, "health: Waited " + (SystemClock.uptimeMillis() - beforeWait)309 + "ms and received the update.");310 traceEnd();311 }onBootPhaseonBootPhase()函数主要是注册一个监听器,检测低电量警告的电量值是否改变,然后调用updateBatteryWarningLevelLocked()函数。250 public voID onBootPhase(int phase) {251 if (phase == PHASE_ACTIVITY_MANAGER_READY) {252 // check our power situation Now that it is safe to display the shutdown dialog.253 synchronized (mlock) {254 ContentObserver obs = new ContentObserver(mHandler) {255 @OverrIDe256 public voID onChange(boolean selfChange) {257 synchronized (mlock) {258 updateBatteryWarningLevelLocked();259 }260 }261 };//监听设置中低电量警告的电量值是否改变,改变时调用updateBatteryWarningLevelLocked函数262 final ContentResolver resolver = mContext.getContentResolver();263 resolver.registerContentObserver(Settings.Global.getUriFor(264 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),265 false, obs, UserHandle.USER_ALL);266 updateBatteryWarningLevelLocked();267 }268 }313 private voID updateBatteryWarningLevelLocked() {314 final ContentResolver resolver = mContext.getContentResolver();//获取默认的警告电量值315 int defWarnLevel = mContext.getResources().getInteger(316 com.androID.internal.R.integer.config_lowBatteryWarningLevel);//获取默认的警告电量值317 mLowBatteryWarningLevel = Settings.Global.getInt(resolver,318 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);319 if (mLowBatteryWarningLevel == 0) {320 mLowBatteryWarningLevel = defWarnLevel;321 }322 if (mLowBatteryWarningLevel < mCriticalbatterylevel) {323 mLowBatteryWarningLevel = mCriticalbatterylevel;324 }//计算出关闭警告的电量值325 mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(326 com.androID.internal.R.integer.config_lowBatteryCloseWarningBump);//调用该方法来真正的更新电池信息327 processValuesLocked(true);328 }在该方法中主要来计算获取警告的电量值和关闭警告的电量值,然后调用processValuesLocked()方法来做真正的更新。我们知道当监听的底层电池电量发生变化的时候,回调update()方法,最终也会调用该方法来更新,那就来分析下该方法的具体实现。466 private voID processValuesLocked(boolean force) {467 boolean logoutlIEr = false;468 long dischargeDuration = 0;469470 mbatterylevelCritical =471 mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNowN472 && mHealthInfo.batterylevel <= mCriticalbatterylevel;473 if (mHealthInfo.chargerAcOnline) {474 mPlugType = BatteryManager.BATTERY_PLUGGED_AC; //充电状态475 } else if (mHealthInfo.chargerUsbOnline) {476 mPlugType = BatteryManager.BATTERY_PLUGGED_USB; usb连击477 } else if (mHealthInfo.chargerWirelessOnline) {478 mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 无线充电479 } else {480 mPlugType = BATTERY_PLUGGED_NONE;481 }// 判断当前是否是危险电量状态 根据底层提供的电池数据,判断当前手机的充电状态490 // Let the battery stats keep track of the current level.491 try {//电池属性改变的时候,会将全部信息写到mBatteryStats中,app端从mBatteryStats中获取当前电池的电量以及状态492 mBatteryStats.setBatteryState(mHealthInfo.batteryStatus, mHealthInfo.batteryHealth,493 mPlugType, mHealthInfo.batterylevel, mHealthInfo.batteryTemperature,494 mHealthInfo.batteryVoltage, mHealthInfo.batteryChargeCounter,495 mHealthInfo.batteryFullCharge,496 mHealthInfo2p1.batteryChargeTimetoFullNowSeconds);497 } catch (remoteexception e) {498 // Should never happen.499 }500 //电池电量低(batterylevel==0)且未充电时,d出关机对话501 shutdownIfnopowerLocked(); //电池温度过高(默认为68C),d出关机对话框502 shutdownIfOverTempLocked();//强制更新,或电源相关属性发生变化时,进行对应 *** 作504 if (force || (mHealthInfo.batteryStatus != mLastBatteryStatus ||505 mHealthInfo.batteryHealth != mLastBatteryHealth ||506 mHealthInfo.batteryPresent != mLastBatteryPresent ||507 mHealthInfo.batterylevel != mLastbatterylevel ||508 mPlugType != mLastPlugType ||509 mHealthInfo.batteryVoltage != mLastBatteryVoltage ||510 mHealthInfo.batteryTemperature != mLastBatteryTemperature ||511 mHealthInfo.maxChargingCurrent != mLastMaxChargingCurrent ||512 mHealthInfo.maxChargingVoltage != mLastMaxChargingVoltage ||513 mHealthInfo.batteryChargeCounter != mLastChargeCounter ||514 mInvalIDCharger != mLastInvalIDCharger)) {515516 if (mPlugType != mLastPlugType) {//上次是不充电状态,现在开始充电了,即由不充电变为充电状态517 if (mLastPlugType == BATTERY_PLUGGED_NONE) {518 // discharging -> charging state change519 mChargeStartLevel = mHealthInfo.batterylevel;520 mChargeStartTime = SystemClock.elapsedRealtime();521522 final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);523 builder.setType(MetricsEvent.TYPE_ACTION);524 builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mPlugType);525 builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,526 mHealthInfo.batterylevel);527 mMetricslogger.write(builder);528529 // There's no value in this data unless we've discharged at least once and the530 // battery level has changed; so don't log until it does.531 if (mdischargeStartTime != 0 && mdischargeStartLevel != mHealthInfo.batterylevel) {532 dischargeDuration = SystemClock.elapsedRealtime() - mdischargeStartTime;533 logoutlIEr = true;534 EventLog.writeEvent(EventLogTags.BATTERY_disCHARGE, dischargeDuration,535 mdischargeStartLevel, mHealthInfo.batterylevel);536 // make sure we see a discharge event before logging again537 mdischargeStartTime = 0;538 }539 } else if (mPlugType == BATTERY_PLUGGED_NONE) { //即由充电变为不充电状态540 // charging -> discharging or we just powered up //本次充电结束,重新开始计算耗电情况,于是初始化下面的变量541 mdischargeStartTime = SystemClock.elapsedRealtime();542 mdischargeStartLevel = mHealthInfo.batterylevel;543544 long chargeDuration = SystemClock.elapsedRealtime() - mChargeStartTime;545 if (mChargeStartTime != 0 && chargeDuration != 0) {546 final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);547 builder.setType(MetricsEvent.TYPE_disMISS);548 builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mLastPlugType);549 builder.addTaggedData(MetricsEvent.FIELD_CHARGING_DURATION_MILliS,550 chargeDuration);551 builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,552 mChargeStartLevel);553 builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_END,554 mHealthInfo.batterylevel);555 mMetricslogger.write(builder);556 }557 mChargeStartTime = 0;558 }559 } //以下是记录电源的状态信息和电量信息560 if (mHealthInfo.batteryStatus != mLastBatteryStatus ||561 mHealthInfo.batteryHealth != mLastBatteryHealth ||562 mHealthInfo.batteryPresent != mLastBatteryPresent ||563 mPlugType != mLastPlugType) {564 EventLog.writeEvent(EventLogTags.BATTERY_STATUS,565 mHealthInfo.batteryStatus, mHealthInfo.batteryHealth, mHealthInfo.batteryPresent ? 1 : 0,566 mPlugType, mHealthInfo.batteryTechnology);567 }568 if (mHealthInfo.batterylevel != mLastbatterylevel) {569 // Don't do this just from voltage or temperature changes, that is570 // too noisy.571 EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,572 mHealthInfo.batterylevel, mHealthInfo.batteryVoltage, mHealthInfo.batteryTemperature);573 } 电池电量低到危险的程度,且没充电,记录耗电时间574 if (mbatterylevelCritical && !mLastbatterylevelCritical &&575 mPlugType == BATTERY_PLUGGED_NONE) {576 // We want to make sure we log discharge cycle outlIErs577 // if the battery is about to dIE.578 dischargeDuration = SystemClock.elapsedRealtime() - mdischargeStartTime;579 logoutlIEr = true;580 }581 //以下是判断电源是否处于低电模式582 if (!mbatterylevelLow) {583 // Should we Now switch in to low battery mode?584 if (mPlugType == BATTERY_PLUGGED_NONE585 && mHealthInfo.batteryStatus !=586 BatteryManager.BATTERY_STATUS_UNKNowN587 && mHealthInfo.batterylevel <= mLowBatteryWarningLevel) {588 mbatterylevelLow = true;589 }590 } else {591 // Should we Now switch out of low battery mode?592 if (mPlugType != BATTERY_PLUGGED_NONE) {593 mbatterylevelLow = false;594 } else if (mHealthInfo.batterylevel >= mLowBatteryCloseWarningLevel) {595 mbatterylevelLow = false;596 } else if (force && mHealthInfo.batterylevel >= mLowBatteryWarningLevel) {597 // If being forced, the prevIoUs state doesn't matter, we will just598 // absolutely check to see if we are Now above the warning level.599 mbatterylevelLow = false;600 }601 }602603 mSequence++;604605 // Separate broadcast is sent for power connected / not connected606 // since the standard intent will not wake any applications and some607 // applications may want to have smart behavior based on this. //以下是单独发送一些广播信息,通知外界电池属性的变化: //通知进入充电状态,或离开充电状态 //通知电源进入低电模式,或离开低电模式608 if (mPlugType != 0 && mLastPlugType == 0) {609 final Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);610 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);611 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);612 mHandler.post(new Runnable() {613 @OverrIDe614 public voID run() {615 mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);616 }617 });618 }619 else if (mPlugType == 0 && mLastPlugType != 0) {620 final Intent statusIntent = new Intent(Intent.ACTION_POWER_disCONNECTED);621 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);622 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);623 mHandler.post(new Runnable() {624 @OverrIDe625 public voID run() {626 mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);627 }628 });629 }630631 if (shouldSendBatteryLowLocked()) {632 mSentLowBatterybroadcast = true;633 final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);634 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);635 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);636 mHandler.post(new Runnable() {637 @OverrIDe638 public voID run() {639 mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);640 }641 });642 } else if (mSentLowBatterybroadcast &&643 mHealthInfo.batterylevel >= mLowBatteryCloseWarningLevel) {644 mSentLowBatterybroadcast = false;645 final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);646 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);647 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);648 mHandler.post(new Runnable() {649 @OverrIDe650 public voID run() {651 mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);652 }653 });654 }655656 // We are doing this after sending the above broadcasts, so anything processing657 // them will get the new sequence number at that point. (See for example how testing658 // of JobScheduler's BatteryController works.)659 sendBatteryChangedIntentLocked();//通知改变660 if (mLastbatterylevel != mHealthInfo.batterylevel || mLastPlugType != mPlugType) {661 sendbatterylevelChangedIntentLocked();662 }663664665 // Update the battery LED666 mLed.updatelightsLocked();667668 // This needs to be done after sendIntent() so that we get the lastest battery stats.669 if (logoutlIEr && dischargeDuration != 0) {670 logoutlIErLocked(dischargeDuration);671 }672673 mLastBatteryStatus = mHealthInfo.batteryStatus;674 mLastBatteryHealth = mHealthInfo.batteryHealth;675 mLastBatteryPresent = mHealthInfo.batteryPresent;676 mLastbatterylevel = mHealthInfo.batterylevel;677 mLastPlugType = mPlugType;678 mLastBatteryVoltage = mHealthInfo.batteryVoltage;679 mLastBatteryTemperature = mHealthInfo.batteryTemperature;680 mLastMaxChargingCurrent = mHealthInfo.maxChargingCurrent;681 mLastMaxChargingVoltage = mHealthInfo.maxChargingVoltage;682 mLastChargeCounter = mHealthInfo.batteryChargeCounter;683 mLastbatterylevelCritical = mbatterylevelCritical;684 mLastInvalIDCharger = mInvalIDCharger;685 }686 }
总结
以上是内存溢出为你收集整理的基于Android 11 BatteryService 分析全部内容,希望文章能够帮你解决基于Android 11 BatteryService 分析所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)