电池服务的启动过程
BatteryService是在systemServer启动核心服务的时候启动的
1.在SystemServer中启动BatteryService服务
代码路径:/frameworks/base/services/java/com/android/server/SystemServer.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/java/com/android/server/SystemServer.java)259 public static void main(String[] args) { 260 new SystemServer().run(); 261 }
在main中创建一个SystemServer的匿名对象并调用它的run函数
263 public SystemServer() { 264 // Check for factory test mode. 265 mFactoryTestMode = FactoryTest.getMode(); 266 // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot 267 mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed")); 268 }
创建匿名对象,在构造函数中得到启动模式和sys.boot_completed的属性。用来判断是否为正常模式启动和boot启动是否完成。
在run函数中会对系统属性进行初始化设置,并启动一些关键的服务:
391 // Start services. 392 try { 393 traceBeginAndSlog("StartServices"); 394 startBootstrapServices(); 395 startCoreServices();//BatteryService在startCoreServices中创建的 396 startOtherServices(); 397 SystemServerInitThreadPool.shutdown();
例如此次要说明的BatteryService服务就在startCoreServices()函数中
640 /** 641 * Starts some essential services that are not tangled up in the bootstrap process. 642 */ 643 private void startCoreServices() { .................................... 648 649 traceBeginAndSlog("StartBatteryService"); 650 // Tracks the battery level. Requires LightService. 651 mSystemServiceManager.startService(BatteryService.class); 652 traceEnd(); 653 .......................................... 665 }
2. BatteryService的构造方法
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
159 public BatteryService(Context context) { 160 super(context); 161 162 mContext = context; 163 mHandler = new Handler(true /*async*/); 164 mLed = new Led(context, getLocalService(LightsManager.class));//内部类Led,控制不同电量下led灯的颜色 165 mBatteryStats = BatteryStatsService.getService(); //电量统计服务 166 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 167 //以下是根据配置文件,定义不同电量对应的等级 168 mCriticalBatteryLevel = mContext.getResources().getInteger( 169 com.android.internal.R.integer.config_criticalBatteryWarningLevel);//电池危急的电量;当电池电量低于此值时,将强制关机 170 mLowBatteryWarningLevel = mContext.getResources().getInteger( 171 com.android.internal.R.integer.config_lowBatteryWarningLevel);//低电警告的电量;当电池电量低于此值时,系统报警,例如闪烁LED灯等 172 mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger( 173 com.android.internal.R.integer.config_lowBatteryCloseWarningBump);//关闭低电警告的电量;当电池电量高于此值时,结束低电状态,停止警示灯 174 mShutdownBatteryTemperature = mContext.getResources().getInteger( 175 com.android.internal.R.integer.config_shutdownBatteryTemperature);//关闭电池的温度(温度失控,就会出现三星S7爆炸啥的......) 176 177 // watch for invalid charger messages if the invalid_charger switch exists 178 if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {// 监控终端是否连接不匹配的充电器 179 UEventObserver invalidChargerObserver = new UEventObserver() { 180 @Override 181 public void onUEvent(UEvent event) { 182 final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0; 183 synchronized (mLock) { 184 if (mInvalidCharger != invalidCharger) { 185 mInvalidCharger = invalidCharger; 186 } 187 } 188 } 189 }; 190 invalidChargerObserver.startObserving( 191 "DEVPATH=/devices/virtual/switch/invalid_charger"); 192 } 193 } 194
整体来看BatteryService构造函数是比较简单的,主要的目的就是得到一些变量,从资源中获取一些预定的值。
2.3 BatteryService onStart方法
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
onStart方法中 将BatteryService服务注册到ServiceManager,注册了底层电量变换的回调方法,最终调用BatteryService的update方法更新电池信息
195 @Override 196 public void onStart() {
197 IBinder b = ServiceManager.getService("batteryproperties");//获取电源属性服务的BinderProxy对象,电源属性服务运行在android的healthd进程中,对应文件为system/core/healthd/BatteryPropertiesRegistrar.cpp,此处java层通过Binder直接与native层通信 198 final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = 199 IBatteryPropertiesRegistrar.Stub.asInterface(b);//向电源属性服务注册一个回调接口,当电源属性发生变化时,BatteryListener的batteryPropertiesChanged函数将被调用 200 try { 201 batteryPropertiesRegistrar.registerListener(new BatteryListener());//注册底层电量变化的监听,调用update更新电池信息。 202 } catch (RemoteException e) { 203 // Should never happen. 204 } 205 206 mBinderService = new BinderService();//注册BatteryService服务 207 publishBinderService("battery", mBinderService);//注册到service manager进程中 208 publishLocalService(BatteryManagerInternal.class, new LocalService());//对于基于LocalServices管理的对象而言,这个函数调用相当于单例模式的进阶版以后BatteryManagerInternal接口类型的对象,只能有BatteryService的内部类LocalService一个 209 }
BatteryService在onStart函数中主要完成一些服务注册、接口注册的工作
3.1 BatteryPropertiesRegistrar
BatteryPropertiesRegistrar.h的定义:
代码路径:/system/core/healthd/BatteryPropertiesRegistrar.h
(http://androidxref.com/8.0.0_r4/xref/system/core/healthd/BatteryPropertiesRegistrar.h)
17#ifndef HEALTHD_BATTERYPROPERTIES_REGISTRAR_H 18#define HEALTHD_BATTERYPROPERTIES_REGISTRAR_H 19 .................................................. 27 28namespace android { 29 30class BatteryPropertiesRegistrar : public BnBatteryPropertiesRegistrar, 31 public IBinder::DeathRecipient { 32public: 33 void publish(const sp<BatteryPropertiesRegistrar>& service); 34 void notifyListeners(const struct BatteryProperties& props); .......................................... 46}; 47 48}; // namespace android 49 50#endif // HEALTHD_BATTERYPROPERTIES_REGISTRAR_H
BatteryPropertiesRegistrar.cpp的实现
代码路径:/system/core/healthd/BatteryPropertiesRegistrar.cpp
(http://androidxref.com/8.0.0_r4/xref/system/core/healthd/BatteryPropertiesRegistrar.cpp)
30 31namespace android { 32 33void BatteryPropertiesRegistrar::publish( 34 const sp<BatteryPropertiesRegistrar>& service) { 35 defaultServiceManager()->addService(String16("batteryproperties"), service);//注册服务到service manager进程 36} 37 38void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) { 39 Vector<sp<IBatteryPropertiesListener> > listenersCopy; 40 41 // Binder currently may service an incoming oneway transaction whenever an 42 // outbound oneway call is made (if there is already a pending incoming 43 // oneway call waiting). This is considered a bug and may change in the 44 // future. For now, avoid recursive mutex lock while making outbound 45 // calls by making a local copy of the current list of listeners. 46 { 47 Mutex::Autolock _l(mRegistrationLock); 48 listenersCopy = mListeners; 49 } 50 for (size_t i = 0; i < listenersCopy.size(); i++) { 51 listenersCopy[i]->batteryPropertiesChanged(props);//通知观察者 52 } 53} 54 55void BatteryPropertiesRegistrar::registerListener(const sp<IBatteryPropertiesListener>& listener) { 56 { 57 if (listener == NULL) 58 return; 59 Mutex::Autolock _l(mRegistrationLock); 60 // check whether this is a duplicate 61 for (size_t i = 0; i < mListeners.size(); i++) { 62 if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) { 63 return; 64 } 65 } 66 67 mListeners.add(listener);//存储观察者 68 IInterface::asBinder(listener)->linkToDeath(this); 69 } 70 healthd_battery_update();//更新底层的电源状态,最终将调用到BatteryMonitor.cpp的update函数,也是BatteryService第一次启动,注册Listener后,立马就会更新一次电源信息 71} 72 .............................................. 117 118} // namespace android 119
对等的Binder通信结构,即双方的主体均在native层,或都在Java层。 这次是客户端在Java层,服务端在native层。
其实仔细想想,这是完全符合Binder通信架构的。
对于客户端而言,它只需要从service manager进程获取到服务端的BpBinder值,然后利用这个BpBinder值逐步构成Java层的BinderProxy对象(会进一步转化为基于业务的服务代理)。
客户端根本就不要求服务端具有Java层的结构。在实际的通信过程中,客户端数据通过Binder驱动,传到服务端的native层。若native层就能够完成处理过程,就不需要往Java层作进一步的传输,直接返回结果即可。整个处理过程,对于客户端而言,完全是透明的。
3.2 回调接口的作用
BatteryListener的回调接口:
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
936 private final class BatteryListener extends IBatteryPropertiesListener.Stub { 937 @Override public void batteryPropertiesChanged(BatteryProperties props) { 938 final long identity = Binder.clearCallingIdentity(); 939 try { 940 BatteryService.this.update(props);//电源属性发生变化后,回调BatteryService的update函数 941 } finally { 942 Binder.restoreCallingIdentity(identity); 943 } 944 } 945 }
BatteryService的update函数定义:
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
321 private void update(BatteryProperties props) { 322 synchronized (mLock) {//mUpdatesStopped默认为false,通过shell command才有可能改变 323 if (!mUpdatesStopped) { 324 mBatteryProps = props; 325 // Process the new values. 326 processValuesLocked(false);//更新电源相关的信息 327 } else { 328 mLastBatteryProps.set(props); 329 } 330 } 331 }
BatteryService注册回调接口的作用是:更新其维护的电源信息
4. BatteryService onBootPhase方法
4.1 基础知识
在SystemServiceManager中提供了以下接口:代码路径:/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java)
137 public void startBootPhase(final int phase) { 138 if (phase <= mCurrentPhase) { 139 throw new IllegalArgumentException("Next phase must be larger than previous"); 140 } 141 mCurrentPhase = phase; 142 143 Slog.i(TAG, "Starting phase " + mCurrentPhase); 144 try { 145 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase); 146 final int serviceLen = mServices.size(); 147 for (int i = 0; i < serviceLen; i++) { 148 final SystemService service = mServices.get(i);//SystemServer利用SystemServiceManager启动的系统服务,均会保留在mServices中 149 long time = System.currentTimeMillis(); 150 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName()); 151 try { 152 service.onBootPhase(mCurrentPhase);//调用此时已经加入的service的onBootPhase函数 153 } catch (Exception ex) { 154 throw new RuntimeException("Failed to boot service " 155 + service.getClass().getName() 156 + ": onBootPhase threw an exception during phase " 157 + mCurrentPhase, ex); 158 } 159 warnIfTooLong(System.currentTimeMillis() - time, service, "onBootPhase"); 160 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); 161 } 162 } finally { 163 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); 164 } 165 }
SystemServiceManager的startBootPhase函数中的参数,对应于系统启动的不同阶段。 详细的定义在SystemService.java中
代码路径:/frameworks/base/services/core/java/com/android/server/SystemService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/SystemService.java)
49public abstract class SystemService { 50 /* 51 * Boot Phases 52 */ 53 public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency? 54 55 /** 56 * After receiving this boot phase, services can obtain lock settings data. 57 */ 58 public static final int PHASE_LOCK_SETTINGS_READY = 480; 59 60 /** 61 * After receiving this boot phase, services can safely call into core system services 62 * such as the PowerManager or PackageManager. 63 */ 64 public static final int PHASE_SYSTEM_SERVICES_READY = 500; 65 66 /** 67 * After receiving this boot phase, services can broadcast Intents. 68 */ 69 public static final int PHASE_ACTIVITY_MANAGER_READY = 550; 70 71 /** 72 * After receiving this boot phase, services can start/bind to third party apps. 73 * Apps will be able to make Binder calls into services at this point. 74 */ 75 public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; 76 77 /** 78 * After receiving this boot phase, services can allow user interaction with the device. 79 * This phase occurs when boot has completed and the home application has started. 80 * System services may prefer to listen to this phase rather than registering a 81 * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency. 82 */ 83 public static final int PHASE_BOOT_COMPLETED = 1000; 84
以上是原生定义的系统启动的不同阶段
这么做的目的是: SystemServer会依次启动许多服务,但服务之间的功能是相互依赖的。 因此,每个服务刚被启动时,都完成最基本的初始化。当系统运行到某个阶段后,调用SystemServiceManager的startBootPhase函数, 于是所有的服务都可以进一步完成这个阶段可以进行的初始化工作。通过这种方式,每个服务的初始化过程可以按阶段分为好几个部分,增加了不同阶段的初始化工作的清晰度; 同时,每个阶段调用startBootPhase函数,就像一种同步机制一样,让所有服务的初始化进程保持一致的步调。
4.2 BatteryService的onBootPhase
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
211 @Override 212 public void onBootPhase(int phase) { 213 if (phase == PHASE_ACTIVITY_MANAGER_READY) { //BatteryService只需要在PHASE_ACTIVITY_MANAGER_READY后,在进行部分的初始化即可 214 // check our power situation now that it is safe to display the shutdown dialog. 215 synchronized (mLock) { 216 ContentObserver obs = new ContentObserver(mHandler) { 217 @Override 218 public void onChange(boolean selfChange) { 219 synchronized (mLock) { 220 updateBatteryWarningLevelLocked(); 221 } 222 } 223 }; 224 final ContentResolver resolver = mContext.getContentResolver(); 225 resolver.registerContentObserver(Settings.Global.getUriFor( 226 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), 227 false, obs, UserHandle.USER_ALL);//监听设置中低电量警告的电量值是否改变,改变时调用updateBatteryWarningLevelLocked函数 228 updateBatteryWarningLevelLocked(); 229 }
230 } 231 } 232
BatteryService的onBootPhase函数主要是注册一个监听器,检测低电量警告的电量值是否改变,然后调用updateBatteryWarningLevelLocked函数
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
233 private void updateBatteryWarningLevelLocked() { 234 final ContentResolver resolver = mContext.getContentResolver(); 235 int defWarnLevel = mContext.getResources().getInteger( 236 com.android.internal.R.integer.config_lowBatteryWarningLevel);//获取XML中配置的默认警告电量值 237 mLowBatteryWarningLevel = Settings.Global.getInt(resolver, 238 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel); //获取设置中用户定义的电量警告值 239 if (mLowBatteryWarningLevel == 0) {//用户没有定义,则使用默认的 240 mLowBatteryWarningLevel = defWarnLevel; 241 } 242 if (mLowBatteryWarningLevel < mCriticalBatteryLevel) {//警告值不能低于危险值 243 mLowBatteryWarningLevel = mCriticalBatteryLevel; 244 } 245 mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(//计算出关闭警告的电量值 246 com.android.internal.R.integer.config_lowBatteryCloseWarningBump); 247 processValuesLocked(true);//更新电池信息 248 }
updateBatteryWarningLevelLocked函数主要关注低电提醒相关的变量更新,然后将剩余的工作交给processValuesLocked处理
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
333 private void processValuesLocked(boolean force) {//force表示是否强制更新信息,当force为false时,只有新旧信息不一致才更新 334 boolean logOutlier = false; 335 long dischargeDuration = 0; 336 337 mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);//判断当前电量是否危险;mBatteryProps由电源属性服务提供 338 if (mBatteryProps.chargerAcOnline) {//得到充电的类型 339 mPlugType = BatteryManager.BATTERY_PLUGGED_AC;//充电状态 340 } else if (mBatteryProps.chargerUsbOnline) { 341 mPlugType = BatteryManager.BATTERY_PLUGGED_USB;//Usb链接状态 342 } else if (mBatteryProps.chargerWirelessOnline) { 343 mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;//无线充电状态 344 } else { 345 mPlugType = BATTERY_PLUGGED_NONE;//未充电状态 346 } 347 348 if (DEBUG) { 349 Slog.d(TAG, "Processing new values: " 350 + "chargerAcOnline=" + mBatteryProps.chargerAcOnline 351 + ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline 352 + ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline 353 + ", maxChargingCurrent" + mBatteryProps.maxChargingCurrent 354 + ", maxChargingVoltage" + mBatteryProps.maxChargingVoltage 355 + ", batteryStatus=" + mBatteryProps.batteryStatus 356 + ", batteryHealth=" + mBatteryProps.batteryHealth 357 + ", batteryPresent=" + mBatteryProps.batteryPresent 358 + ", batteryLevel=" + mBatteryProps.batteryLevel 359 + ", batteryTechnology=" + mBatteryProps.batteryTechnology 360 + ", batteryVoltage=" + mBatteryProps.batteryVoltage 361 + ", batteryChargeCounter=" + mBatteryProps.batteryChargeCounter 362 + ", batteryFullCharge=" + mBatteryProps.batteryFullCharge 363 + ", batteryTemperature=" + mBatteryProps.batteryTemperature 364 + ", mBatteryLevelCritical=" + mBatteryLevelCritical 365 + ", mPlugType=" + mPlugType); 366 } 367 368 // Let the battery stats keep track of the current level. 369 try {//将信息递交给电源统计服务 370 mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, 371 mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature, 372 mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter, 373 mBatteryProps.batteryFullCharge); 374 } catch (RemoteException e) { 375 // Should never happen. 376 } 377 378 shutdownIfNoPowerLocked();//电池电量低(batteryLevel==0)且未充电时,拉起关机对话框 379 shutdownIfOverTempLocked();//电池温度过高(默认为68C),拉起关机对话框 380 //强制更新,或电源相关属性发生变化时,进行对应操作 381 if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus || 382 mBatteryProps.batteryHealth != mLastBatteryHealth || 383 mBatteryProps.batteryPresent != mLastBatteryPresent || 384 mBatteryProps.batteryLevel != mLastBatteryLevel || 385 mPlugType != mLastPlugType || 386 mBatteryProps.batteryVoltage != mLastBatteryVoltage || 387 mBatteryProps.batteryTemperature != mLastBatteryTemperature || 388 mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent || 389 mBatteryProps.maxChargingVoltage != mLastMaxChargingVoltage || 390 mBatteryProps.batteryChargeCounter != mLastChargeCounter || 391 mInvalidCharger != mLastInvalidCharger)) { 392 393 if (mPlugType != mLastPlugType) {//充电状态发生变化(不关注充电的方式,即usb变为AC之类的,只是关注充电变为未充电等事件) 394 if (mLastPlugType == BATTERY_PLUGGED_NONE) { 395 // discharging -> charging 396 397 // There's no value in this data unless we've discharged at least once and the 398 // battery level has changed; so don't log until it does. 399 if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {//记录一下不充电待机的情况下,耗电量及耗电时长 400 dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime; 401 logOutlier = true; 402 EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration, 403 mDischargeStartLevel, mBatteryProps.batteryLevel); 404 // make sure we see a discharge event before logging again 405 mDischargeStartTime = 0; 406 } 407 } else if (mPlugType == BATTERY_PLUGGED_NONE) {//本次充电结束,重新开始计算耗电情况,于是初始化下面的变量 408 // charging -> discharging or we just powered up 409 mDischargeStartTime = SystemClock.elapsedRealtime(); 410 mDischargeStartLevel = mBatteryProps.batteryLevel; 411 } 412 }//记录电源的状态信息、电量信息 413 if (mBatteryProps.batteryStatus != mLastBatteryStatus || 414 mBatteryProps.batteryHealth != mLastBatteryHealth || 415 mBatteryProps.batteryPresent != mLastBatteryPresent || 416 mPlugType != mLastPlugType) { 417 EventLog.writeEvent(EventLogTags.BATTERY_STATUS, 418 mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0, 419 mPlugType, mBatteryProps.batteryTechnology); 420 } 421 if (mBatteryProps.batteryLevel != mLastBatteryLevel) { 422 // Don't do this just from voltage or temperature changes, that is 423 // too noisy. 424 EventLog.writeEvent(EventLogTags.BATTERY_LEVEL, 425 mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature); 426 }//电池电量低到危险的程度,且没充电,记录耗电时间 427 if (mBatteryLevelCritical && !mLastBatteryLevelCritical && 428 mPlugType == BATTERY_PLUGGED_NONE) { 429 // We want to make sure we log discharge cycle outliers 430 // if the battery is about to die. 431 dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime; 432 logOutlier = true; 433 } 434 //判断电源是否处于低电模式 435 if (!mBatteryLevelLow) { 436 // Should we now switch in to low battery mode? 437 if (mPlugType == BATTERY_PLUGGED_NONE 438 && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) { 439 mBatteryLevelLow = true;// 当前未充电,且当前电量小于提醒电量,设置低电量为true 440 } 441 } else { 442 // Should we now switch out of low battery mode? 443 if (mPlugType != BATTERY_PLUGGED_NONE) { 444 mBatteryLevelLow = false;//开始充电,退出低电量模式 445 } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) { 446 mBatteryLevelLow = false;//电池电量充足,退出低电量模式 447 } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) { 448 // If being forced, the previous state doesn't matter, we will just 449 // absolutely check to see if we are now above the warning level. 450 mBatteryLevelLow = false;//强制刷新时,忽略之前的状态 451 } 452 } 453 454 mSequence++; 455 456 // Separate broadcast is sent for power connected / not connected 457 // since the standard intent will not wake any applications and some 458 // applications may want to have smart behavior based on this. 459 if (mPlugType != 0 && mLastPlugType == 0) { 460 final Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED); 461 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 462 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence); 463 mHandler.post(new Runnable() { 464 @Override 465 public void run() { 466 mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL); 467 } 468 }); 469 } 470 else if (mPlugType == 0 && mLastPlugType != 0) { 471 final Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED); 472 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 473 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence); 474 mHandler.post(new Runnable() { 475 @Override 476 public void run() { 477 mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL); 478 } 479 }); 480 } 481 482 if (shouldSendBatteryLowLocked()) { 483 mSentLowBatteryBroadcast = true; 484 final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW); 485 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 486 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence); 487 mHandler.post(new Runnable() { 488 @Override 489 public void run() { 490 mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL); 491 } 492 }); 493 } else if (mSentLowBatteryBroadcast && 494 mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) { 495 mSentLowBatteryBroadcast = false; 496 final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY); 497 statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 498 statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence); 499 mHandler.post(new Runnable() { 500 @Override 501 public void run() { 502 mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL); 503 } 504 }); 505 } 506 507 // We are doing this after sending the above broadcasts, so anything processing 508 // them will get the new sequence number at that point. (See for example how testing 509 // of JobScheduler's BatteryController works.) 510 sendIntentLocked();//发送广播ACTION_BATTERY_CHANGED,内含电源当前的全部信息 511 512 // Update the battery LED 513 mLed.updateLightsLocked();//根据电源的电量和状态,改变LED灯的颜色 514 515 // This needs to be done after sendIntent() so that we get the lastest battery stats. 516 if (logOutlier && dischargeDuration != 0) { 517 logOutlierLocked(dischargeDuration);//利用BatteryInfoService记录耗电情况的dump文件 518 } 519 //更新本地变量 520 mLastBatteryStatus = mBatteryProps.batteryStatus; 521 mLastBatteryHealth = mBatteryProps.batteryHealth; 522 mLastBatteryPresent = mBatteryProps.batteryPresent; 523 mLastBatteryLevel = mBatteryProps.batteryLevel; 524 mLastPlugType = mPlugType; 525 mLastBatteryVoltage = mBatteryProps.batteryVoltage; 526 mLastBatteryTemperature = mBatteryProps.batteryTemperature; 527 mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent; 528 mLastMaxChargingVoltage = mBatteryProps.maxChargingVoltage; 529 mLastChargeCounter = mBatteryProps.batteryChargeCounter; 530 mLastBatteryLevelCritical = mBatteryLevelCritical; 531 mLastInvalidCharger = mInvalidCharger; 532 } 533 }
代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)
mLed.updateLightsLocked
881 private final class Led { 882 private final Light mBatteryLight; 883 884 private final int mBatteryLowARGB; 885 private final int mBatteryMediumARGB; 886 private final int mBatteryFullARGB; 887 private final int mBatteryLedOn; 888 private final int mBatteryLedOff; 889 890 public Led(Context context, LightsManager lights) { 891 mBatteryLight = lights.getLight(LightsManager.LIGHT_ID_BATTERY); 892 893 mBatteryLowARGB = context.getResources().getInteger( 894 com.android.internal.R.integer.config_notificationsBatteryLowARGB); 895 mBatteryMediumARGB = context.getResources().getInteger( 896 com.android.internal.R.integer.config_notificationsBatteryMediumARGB); 897 mBatteryFullARGB = context.getResources().getInteger( 898 com.android.internal.R.integer.config_notificationsBatteryFullARGB); 899 mBatteryLedOn = context.getResources().getInteger( 900 com.android.internal.R.integer.config_notificationsBatteryLedOn); 901 mBatteryLedOff = context.getResources().getInteger( 902 com.android.internal.R.integer.config_notificationsBatteryLedOff); 903 } 904 905 /** 906 * Synchronize on BatteryService. 907 */ 908 public void updateLightsLocked() { 909 final int level = mBatteryProps.batteryLevel; 910 final int status = mBatteryProps.batteryStatus; 911 if (level < mLowBatteryWarningLevel) {//电量低于BatteryWarning的电量 912 if (status == BatteryManager.BATTERY_STATUS_CHARGING) {//已经连接上充电 913 // Solid red when battery is charging 914 mBatteryLight.setColor(mBatteryLowARGB);//指示灯显示红色 915 } else { 916 // Flash red when battery is low and not charging 917 mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED, 918 mBatteryLedOn, mBatteryLedOff);//没有连接充电线,红灯闪烁 919 } 920 } else if (status == BatteryManager.BATTERY_STATUS_CHARGING 921 || status == BatteryManager.BATTERY_STATUS_FULL) {//当前正在充电或者当前电量已经充满 922 if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) { 923 // Solid green when full or charging and nearly full 924 mBatteryLight.setColor(mBatteryFullARGB);//当电池已经充满或者快要充满的时候指示灯显示绿色 925 } else { 926 // Solid orange when charging and halfway full 927 mBatteryLight.setColor(mBatteryMediumARGB);//当正在充电或者电量超过一半的时候,指示灯显示橘黄色 928 } 929 } else { 930 // No lights if not charging and not low 931 mBatteryLight.turnOff();//其他正常情况指示灯关闭 932 } 933 } 934 }
更新LED等方法主要根据电池电量和充电状态来决定LED指示灯的颜色和显示方式。低于警告电量的时候LED指示灯显示红色,当电池充满电的时候指示灯显示绿色
从BatteryService整个代码结构来看,BatterySerivce负责与native层通信,更新fwk中维护的电源信息。 BatteryService既通过广播的方式将信息发送给观察者,也提供了接口供外界调用。 同时,BatteryService提供的信息应该是BatteryStatsService统计的重要依据。