Android电池

来源:互联网 发布:ubuntu wine 迅雷 编辑:程序博客网 时间:2024/04/28 23:21

Android电池

Android电池系列三之BatteryService

前置文章

  1. 《Android电池-Android电池概述》
  2. 《Android电池-Android电池守护进程》

前言

在上篇文章《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 完成的功能还是比较简单。

  1. 第一接收 Native 层上报的电池数据
  2. 第二通知 BatteryStatsService 数据的变化
  3. 广播电池数据的变化

另外,还有如下两个功能,本文不再阐述他们的过程。

  1. 电池 led 的处理(充电提示灯常亮,低电量闪烁等)
原创粉丝点击