Android电池
Android电池系列三之BatteryService
前置文章
前言
在上篇文章《Android电池-Android电池守护进程》中,我们学习了 Android 电池状态变化的传递框架,其中从 Native 层传送到 Framework 层时,Framework 层就是由 BatteryService 完成这一任务。
BatteryService概述
BatteryService 的定义如下:
public final class BatteryService extends SystemService {
.....
}
这个类定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。
在笔者的文章《Android系统之System Server大纲》一文中,有详细介绍继承 SystemService 的 Service 的特点,因此,在 BatteryService 启动的时候,会回调方法 onStart()。
这里顺便粘贴一下 BatteryService 的启动代码,如果读者想了解更多 Android Service 的内容,可以阅读文章《Android系统之System Server大纲》。
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);
}
这个方法定义在文件 frameworks/base/services/java/com/android/server/SystemServer.java 中。
BatteryService 的 onStart() 方法定义如下:
public void onStart() {
//首先注册Battery Listener 到 BatteryPropertiesRegistrar
IBinder b = ServiceManager.getService("batteryproperties");
final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
IBatteryPropertiesRegistrar.Stub.asInterface(b);
try {
batteryPropertiesRegistrar.registerListener(new BatteryListener());
} catch (RemoteException e) {
// Should never happen.
}
//添加Service到ServiceManager
mBinderService = new BinderService();
publishBinderService("battery", mBinderService);
publishLocalService(BatteryManagerInternal.class, new LocalService());
}
这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。
在这个方法中,我们重点关注注册 BatteryProperties 监听器。在文章《Android电池-Android电池守护进程》中,我们已经了解 BatteryPropertiesRegistrar 这个 Service 的创建过程和作用。BatteryPropertiesRegistrar 的 Server 端运行在 healthd 进程中,实现上层注册 BatteryProperties 监听器,从而实现 Battery 状态由 Native 上报到 Framework 或者 App 层。
在文章《Android电池-Android电池守护进程》中,我们已经了解,如果电池状态有任何变化,会执行如下代码:
void healthd_mode_android_battery_update(
struct android::BatteryProperties *props) {
if (gBatteryPropertiesRegistrar != NULL)
//通知 framework 或 app
gBatteryPropertiesRegistrar->notifyListeners(*props);
return;
}
这个函数定义在文件 system/core/healthd/healthd_mode_android.cpp 中。
notifyListeners(*props) 实际上就会调用到 BatteryService 中注册的 BatteryListener 的 batteryPropertiesChanged() 方法。BatteryListener 的定义如下:
private final class BatteryListener extends IBatteryPropertiesListener.Stub {
@Override public void batteryPropertiesChanged(BatteryProperties props) {
final long identity = Binder.clearCallingIdentity();
try {
BatteryService.this.update(props);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。
当然,在方法 batteryPropertiesChanged() 中,看不到什么有用的信息,因为这里直接调用了 BatteryService.this.update() 把任务转移到 BatterService。
BatteryService接收电池状态
在上面章节 BatteryService概述 中,我们已经知道 BatteryService 是如何地接收 healthd 上报的电池的状态变化。下面我们接着看 BatteryService 接收到电池变化数据后,如果处理这些变化,BatteryService 的 update() 方法定义如下:
private void update(BatteryProperties props) {
synchronized (mLock) {
.....
if (!mUpdatesStopped) {
processValuesLocked(false);
.....
}
}
这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。
这里,有一个 mUpdatesStopped 的条件判断,也就是说,可以打开或关闭电池状态的更新,可以通过命令来实现这个功能,详情可查阅 onStart() 方法中的 BinderService。我们继续往下跟踪 processValuesLocked() 做了什么事情。
private void processValuesLocked(boolean force) {
//这里从上报的的BatteryProperties中取出数据赋值到 BatteryService中的变量
//包括电量,充电状态,电压,温度等等,这里省略其它的赋值代码
mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
if (mBatteryProps.chargerAcOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mBatteryProps.chargerUsbOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
.....
//更新电池状态变化到 BatterStatsService,下篇文章我们再阐述它
mBatteryStats.setBatteryState(mBatteryProps.batteryStatus,...)
//处理电量过低处理关机事宜
shutdownIfNoPowerLocked();
//处理电池温度异常关机事宜
shutdownIfOverTempLocked();
//插上电源广播Intent.ACTION_POWER_CONNECTED
if (mPlugType != 0 && mLastPlugType == 0) {
Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
.....
}else if (mPlugType == 0 && mLastPlugType != 0) {
//断开电源广播Intent.ACTION_POWER_DISCONNECTED
Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
.....
}
if (shouldSendBatteryLowLocked()) {
//低电量广播Intent.ACTION_BATTERY_LOW
Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
} else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {
//取消低电量广播Intent.ACTION_BATTERY_OKAY
Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
}
//电池状态变化广播Intent.ACTION_BATTERY_CHANGED
sendIntentLocked();
}
这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。
在这个方法中,所完成的任务都在源码的注释中写明了,我们再详细看看 sendIntentLocked() 这个方法,具体会传送那些数据到相应的广播接收器
private void sendIntentLocked() {
// Pack up the values and broadcast them to everyone
final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
int icon = getIconLocked(mBatteryProps.batteryLevel);
intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
intent.putExtra(BatteryManager.EXTRA_STATUS_SMARTBOOK, mBatteryProps.batteryStatus_smb);
intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
intent.putExtra(BatteryManager.EXTRA_PRESENT_SMARTBOOK, mBatteryProps.batteryPresent_smb);
intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
intent.putExtra(BatteryManager.EXTRA_LEVEL_SMARTBOOK, mBatteryProps.batteryLevel_smb);
intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryProps.batteryVoltage);
intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature);
intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology);
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
mHandler.post(new Runnable() {
@Override
public void run() {
ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
}
});
这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。
在这个方法中,当电池状态变化后,会发送广播 Intent.ACTION_BATTERY_CHANGED 通知 App 等,并在 Intent 中传送电池状态的数据,状态,电量,电压等等。
总结
BatteryService 的功能到这里就介绍完毕了,BatteryService 完成的功能还是比较简单。
- 第一接收 Native 层上报的电池数据
- 第二通知 BatteryStatsService 数据的变化
- 广播电池数据的变化
另外,还有如下两个功能,本文不再阐述他们的过程。
- 电池 led 的处理(充电提示灯常亮,低电量闪烁等)