最近遇到个新的需求,当电池温度过高以及OVP状态的时候,在用户界面提示信息。
电池电源信息相关在Framework层/
与电池电量信息等相关类:
1.BatteryManager.java
2.BatteryProperties.java
3.BatteryStates.java
4.PowerUI.java
5.LightService.java
6.PowerManager.java
7.BatteryService.java
这里先分析BatteryService.java。
源码路径:
***/framework/base/services/java/com/android/server/BatteryService.java
BatteryService.java代码,必要的地方做了处理。
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server;
import android.os.BatteryStats;
import com.android.internal.app.IBatteryStats;
import com.android.server.am.BatteryStatsService;
import android.app.ActivityManagerNative;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.os.BatteryProperties;
import android.os.Binder;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBatteryPropertiesListener;
import android.os.IBatteryPropertiesRegistrar;
import android.os.IBinder;
import android.os.DropBoxManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UEventObserver;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.EventLog;
import android.util.Slog;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
/**
* <p>BatteryService monitors the charging status, and charge level of the device
* battery. When these values change this service broadcasts the new values
* to all {@link android.content.BroadcastReceiver IntentReceivers} that are
* watching the {@link android.content.Intent#ACTION_BATTERY_CHANGED
* BATTERY_CHANGED} action.</p>
* <p>The new values are stored in the Intent data and can be retrieved by
* calling {@link android.content.Intent#getExtra Intent.getExtra} with the
* following keys:</p>
* <p>"scale" - int, the maximum value for the charge level</p>
* <p>"level" - int, charge level, from 0 through "scale" inclusive</p>
* <p>"status" - String, the current charging status.<br />
* <p>"health" - String, the current battery health.<br />
* <p>"present" - boolean, true if the battery is present<br />
* <p>"icon-small" - int, suggested small icon to use for this state</p>
* <p>"plugged" - int, 0 if the device is not plugged in; 1 if plugged
* into an AC power adapter; 2 if plugged in via USB.</p>
* <p>"voltage" - int, current battery voltage in millivolts</p>
* <p>"temperature" - int, current battery temperature in tenths of
* a degree Centigrade</p>
* <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p>
*
* <p>
* The battery service may be called by the power manager while holding its locks so
* we take care to post all outcalls into the activity manager to a handler.
*
* FIXME: Ideally the power manager would perform all of its calls into the battery
* service asynchronously itself.
* </p>
*/
public final class BatteryService extends Binder {
private static final String TAG = BatteryService.class.getSimpleName();
private static final boolean DEBUG = false;
//电量百分比显示
private static final int BATTERY_SCALE = 100; // battery capacity is a percentage
// Used locally for determining when to make a last ditch effort to log
// discharge stats before the device dies.
private int mCriticalBatteryLevel;
private static final int DUMP_MAX_LENGTH = 24 * 1024;
private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "--unplugged" };
private static final String DUMPSYS_DATA_PATH = "/data/system/";
// This should probably be exposed in the API, though it's not critical
//没有充电状态则显示0
private static final int BATTERY_PLUGGED_NONE = 0;
private final Context mContext;
private final IBatteryStats mBatteryStats;
private final Handler mHandler;
private final Object mLock = new Object();
private BatteryProperties mBatteryProps;
private boolean mBatteryLevelCritical;
private int mLastBatteryStatus;
private int mLastBatteryHealth;
private boolean mLastBatteryPresent;
private int mLastBatteryLevel;
private int mLastBatteryVoltage;
private int mLastBatteryTemperature;
private boolean mLastBatteryLevelCritical;
private int mInvalidCharger;
private int mLastInvalidCharger;
private int mLowBatteryWarningLevel;
private int mLowBatteryCloseWarningLevel;
private int mShutdownBatteryTemperature;
private int mPlugType;
private int mLastPlugType = -1; // Extra state so we can detect first run
private long mDischargeStartTime;
private int mDischargeStartLevel;
private boolean mUpdatesStopped;
private Led mLed;
private boolean mSentLowBatteryBroadcast = false;
private BatteryListener mBatteryPropertiesListener;
private IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar;
public BatteryService(Context context, LightsService lights) {
mContext = context;
mHandler = new Handler(true /*async*/);
mLed = new Led(context, lights);
mBatteryStats = BatteryStatsService.getService();
mCriticalBatteryLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
//res/res/values/config.xml:547: <integer name="config_lowBatteryWarningLevel">15</integer>
mLowBatteryWarningLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel);
//res/res/values/config.xml:550: <integer name="config_lowBatteryCloseWarningLevel">20</integer> 接近警戒值。
mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
//res/res/values/config.xml:544: <integer name="config_shutdownBatteryTemperature">680</integer>//68度?为什么?
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");
}
//注册监听。实时更新电池电量信息,底层传递上来的电池信息有变化时,则上层会做响应的处理。
//从这里可以看出回调接口中调用的update()方法应该是比较频繁的。
mBatteryPropertiesListener = new BatteryListener();
IBinder b = ServiceManager.getService("batterypropreg");
mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
try {
mBatteryPropertiesRegistrar.registerListener(mBatteryPropertiesListener);
} catch (RemoteException e) {
// Should never happen.
}
}
//该方法在SystemServer.java中调用。开机过程。
void systemReady() {
// check our power situation now that it is safe to display the shutdown dialog.
synchronized (mLock) {
shutdownIfNoPowerLocked();
shutdownIfOverTempLocked();
}
}
/**
* Returns true if the device is plugged into any of the specified plug types.
*/
public boolean isPowered(int plugTypeSet) {
synchronized (mLock) {
return isPoweredLocked(plugTypeSet);
}
}
//当前手机是否正在充电。这里面查查&的相关用法。
private boolean isPoweredLocked(int plugTypeSet) {
// assume we are powered if battery state is unknown so
// the "stay on while plugged in" option will work.
if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
return true;
}
if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mBatteryProps.chargerAcOnline) {
return true;
}
if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mBatteryProps.chargerUsbOnline) {
return true;
}
if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mBatteryProps.chargerWirelessOnline) {
return true;
}
return false;
}
/**
* Returns the current plug type.
*/
public int getPlugType() {
synchronized (mLock) {
return mPlugType;
}
}
/**
* Returns battery level as a percentage.
*/
public int getBatteryLevel() {
synchronized (mLock) {
return mBatteryProps.batteryLevel;
}
}
/**
* Returns true if battery level is below the first warning threshold.
*/
public boolean isBatteryLow() {
synchronized (mLock) {
return mBatteryProps.batteryPresent && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel;
}
}
/**
* Returns a non-zero value if an unsupported charger is attached.
*/
public int getInvalidCharger() {
synchronized (mLock) {
return mInvalidCharger;
}
}
private void shutdownIfNoPowerLocked() {
// shut down gracefully if our battery is critically low and we are not powered.
// wait until the system