先貼一張類與類之間的關係圖:java
![](http://static.javashuo.com/static/loading.gif)
構造函數只是從資源中取一些值。android
- public BatteryService(Context context) {
- super(context);
-
- mContext = context;
- mHandler = new Handler(true /*async*/);
- mLed = new Led(context, getLocalService(LightsManager.class));
- mBatteryStats = BatteryStatsService.getService();
-
- 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);
-
- // watch for invalid charger messages if the invalid_charger switch exists
- if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
- mInvalidChargerObserver.startObserving(
- "DEVPATH=/devices/virtual/switch/invalid_charger");
- }
- }
onstart函數將電池監聽註冊到底層去。app
[java] view plain copyless
- @Override
- public void onStart() {
- IBinder b = ServiceManager.getService("batteryproperties");
- final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
- IBatteryPropertiesRegistrar.Stub.asInterface(b);
- try {
- //電池監聽,註冊到底層。當底層電量改變會調用此監聽。而後執行update
- batteryPropertiesRegistrar.registerListener(new BatteryListener());
- } catch (RemoteException e) {
- // Should never happen.
- }
-
- publishBinderService("battery", new BinderService());
- publishLocalService(BatteryManagerInternal.class, new LocalService());
- }
將本地接口publish出去。async
[java] view plain copyide
- private final class LocalService extends BatteryManagerInternal {
- @Override
- public boolean isPowered(int plugTypeSet) {
- synchronized (mLock) {
- return isPoweredLocked(plugTypeSet);
- }
- }
-
- @Override
- public int getPlugType() {
- synchronized (mLock) {
- return mPlugType;
- }
- }
-
- @Override
- public int getBatteryLevel() {
- synchronized (mLock) {
- return mBatteryProps.batteryLevel;
- }
- }
-
- @Override
- public boolean getBatteryLevelLow() {
- synchronized (mLock) {
- return mBatteryLevelLow;
- }
- }
-
- @Override
- public int getInvalidCharger() {
- synchronized (mLock) {
- return mInvalidCharger;
- }
- }
- }
當底層有信息上來,會調用update函數更新BatteryService中的狀態值。函數
[java] view plain copypost
- private void update(BatteryProperties props) {
- synchronized (mLock) {
- if (!mUpdatesStopped) {
- mBatteryProps = props;
- // Process the new values.
- processValuesLocked(false);
- } else {
- mLastBatteryProps.set(props);
- }
- }
- }
接下來分析主函數processValuesLocked:this
[java] view plain copyspa
- private void processValuesLocked(boolean force) {
- boolean logOutlier = false;
- long dischargeDuration = 0;
-
- mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
- //解析充電類型
- if (mBatteryProps.chargerAcOnline) {
- mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
- } else if (mBatteryProps.chargerUsbOnline) {
- mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
- } else if (mBatteryProps.chargerWirelessOnline) {
- mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
- } else {
- mPlugType = BATTERY_PLUGGED_NONE;
- }
-
-
- // Let the battery stats keep track of the current level.
- try {
- mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
- mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
- mBatteryProps.batteryVoltage);
- } catch (RemoteException e) {
- // Should never happen.
- }
- //沒電了
- shutdownIfNoPowerLocked();
- //溫度太高
- shutdownIfOverTempLocked();
- //force用來控制是否第一次調用
- if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
- mBatteryProps.batteryHealth != mLastBatteryHealth ||
- mBatteryProps.batteryPresent != mLastBatteryPresent ||
- mBatteryProps.batteryLevel != mLastBatteryLevel ||
- mPlugType != mLastPlugType ||
- mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
- mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
- mInvalidCharger != mLastInvalidCharger)) {
-
- if (mPlugType != mLastPlugType) {
- if (mLastPlugType == BATTERY_PLUGGED_NONE) {
-
- //不充電到充電
- if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {
- dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
- logOutlier = true;
- EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
- mDischargeStartLevel, mBatteryProps.batteryLevel);
- // make sure we see a discharge event before logging again
- mDischargeStartTime = 0;
- }
- } else if (mPlugType == BATTERY_PLUGGED_NONE) {
- // 剛開始充電
- mDischargeStartTime = SystemClock.elapsedRealtime();
- mDischargeStartLevel = mBatteryProps.batteryLevel;
- }
- }
-
- if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
- mPlugType == BATTERY_PLUGGED_NONE) {
- // We want to make sure we log discharge cycle outliers
- // if the battery is about to die.
- dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
- logOutlier = true;
- }
-
- if (!mBatteryLevelLow) {
- // Should we now switch in to low battery mode?
- if (mPlugType == BATTERY_PLUGGED_NONE
- && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
- mBatteryLevelLow = true;
- }
- } else {
- // Should we now switch out of low battery mode?
- if (mPlugType != BATTERY_PLUGGED_NONE) {
- mBatteryLevelLow = false;
- } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
- mBatteryLevelLow = false;
- } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
- // If being forced, the previous state doesn't matter, we will just
- // absolutely check to see if we are now above the warning level.
- mBatteryLevelLow = false;
- }
- }
- //發送電池狀態變化的廣播
- sendIntentLocked();
-
- // Separate broadcast is sent for power connected / not connected
- // since the standard intent will not wake any applications and some
- // applications may want to have smart behavior based on this.
- if (mPlugType != 0 && mLastPlugType == 0) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
- statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
- }
- });
- }
- else if (mPlugType == 0 && mLastPlugType != 0) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
- statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
- }
- });
- }
-
- if (shouldSendBatteryLowLocked()) {
- mSentLowBatteryBroadcast = true;
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
- statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
- }
- });
- } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {
- mSentLowBatteryBroadcast = false;
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
- statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
- }
- });
- }
-
- //更新電池的LED
- mLed.updateLightsLocked();
-
- // This needs to be done after sendIntent() so that we get the lastest battery stats.
- if (logOutlier && dischargeDuration != 0) {
- logOutlierLocked(dischargeDuration);
- }
-
- mLastBatteryStatus = mBatteryProps.batteryStatus;
- mLastBatteryHealth = mBatteryProps.batteryHealth;
- mLastBatteryPresent = mBatteryProps.batteryPresent;
- mLastBatteryLevel = mBatteryProps.batteryLevel;
- mLastPlugType = mPlugType;
- mLastBatteryVoltage = mBatteryProps.batteryVoltage;
- mLastBatteryTemperature = mBatteryProps.batteryTemperature;
- mLastBatteryLevelCritical = mBatteryLevelCritical;
- mLastInvalidCharger = mInvalidCharger;
- }
- }