美文网首页
第八章:BatteryService

第八章:BatteryService

作者: momxmo | 来源:发表于2020-04-15 16:37 被阅读0次

简介

BatteryService电池服务负责监控设备的充电状态和电量,这些值发生改变时,服务将会发起广播通知电池的状态信息

电池上报流程图

image.png
1.Kernel层

本层属于电池的驱动部分,负责与硬件进行交互,当电池电量信息发生变化时,生成相应的uevent,上报给用户层。
主要相关代码路径:

\linux-4.5\drivers\power\power_supply_core.c
\linux-4.5\drivers\power\power_supply_sysfs.c
2. Healthd守护进程

本层在Android中属于Native层,healthd中运行一个系统服务batteryproperties,负责监听Kernel中上报的uevent,对电池电量进行实时监控。
主要相关代码路径:

\system\core\healthd\healthd.cpp
\system\core\healthd\BatteryMonitor.cpp
\system\core\healthd\BatteryPropertiesRegistrar.cpp
\system\core\healthd\BatteryMonitor.cpp
3.BatteryService系统服务

本层提供了C++/Java两套接口来访问batteryproperties系统服务。
本层的系统服务battery使用Java代码写成,运行在fwk的中SystemServer进程。
该系统服务的主要作用是:监听batteryproperties服务中的电池信息变化消息,并将该消息以系统广播的形式转发至Android系统中各处。
主要相关代码路径:

\frameworks\native\services\batteryservice\IBatteryPropertiesRegistrar.cpp
\frameworks\native\services\batteryservice\IBatteryPropertiesListener.cpp
\frameworks\native\services\batteryservice\BatteryProperties.cpp
\frameworks\base\core\java\android\os\IBatteryPropertiesRegistrar.aidl
\frameworks\base\core\java\android\os\IBatteryPropertiesListener.aidl
\frameworks\base\core\java\android\os\BatteryProperties.java
\frameworks\base\services\core\java\com\android\server\BatteryService.java
4. SystemUI 应用

该部分属于电量上报的最后的环节。其主要工作是:监听系统广播Intent.ACTION_BATTERY_CHANGED,并对UI作出相应更新。
主要相关代码路径:

\frameworks\base\packages\SystemUI\src\com\android\systemui\power\PowerUI.java

一、初始化

跟其他系统服务一样, BatteryService也是继承于SystemService并通过SystemServer启动。
1.启动位置
frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {
  private void startCoreServices() {
      ......
mSystemServiceManager.startService(BatteryService.class);
       ......
    }
}

2.构造函数

 public BatteryService(Context context) {
        super(context);

        mContext = context;
        mHandler = new Handler(true /*async*/);
      //Step:1
        mLed = new Led(context, getLocalService(LightsManager.class));
//电池属性改变的时候,会将全部信息写到mBatteryStats中,app端从mBatteryStats中获取当前电池的电量以及状态
        mBatteryStats = BatteryStatsService.getService();
        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
    //Step:2
        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
//Step:3
        if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
            UEventObserver invalidChargerObserver = new UEventObserver() {
                @Override
                public void onUEvent(UEvent event) {
                    final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;
                    synchronized (mLock) {
                        if (mInvalidCharger != invalidCharger) {
                            mInvalidCharger = invalidCharger;
                        }
                    }
                }
            };
            invalidChargerObserver.startObserving(
                    "DEVPATH=/devices/virtual/switch/invalid_charger");
        }
    }
  • 1.控制充电呼吸灯颜色;
  • 2.获取res中常用的battery配置信息,比如电池危急电量、电池低电量模式警告电量、关闭低电量模式警告电量、电池关机温度;
    1. 监控终端是否连接不匹配的充电器
      电量相关常用配置修改路径如下:
      frameworks\base\core\res\res\values\config.xml

3.开始引导
在SystemServiceManager中有一个startBootPhase(final int phase )函数,这个函数有啥作用呢?

android系统的启动,是分为几个阶段的,startBootPhase(final int phase)中的这个phase,就表示android系统的启动目前处于哪个阶段,SystemServiceManager将这个phase传递给每个系统服务,每个服务可以根据不同的阶段去做不同的事情;

 @Override
    public void onStart() {
        IBinder b = ServiceManager.getService("batteryproperties");
        final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
                IBatteryPropertiesRegistrar.Stub.asInterface(b);
        try {
      //Step:1
            batteryPropertiesRegistrar.registerListener(new BatteryListener());
        } catch (RemoteException e) {
            // Should never happen.
        }
        //Step:2
        mBinderService = new BinderService();
        publishBinderService("battery", mBinderService);
        publishLocalService(BatteryManagerInternal.class, new LocalService());
    }

    @Override
    public void onBootPhase(int phase) {
        //Step:3
        if (phase == PHASE_ACTIVITY_MANAGER_READY) {
            // check our power situation now that it is safe to display the shutdown dialog.
            synchronized (mLock) {
                ContentObserver obs = new ContentObserver(mHandler) {
                    @Override
                    public void onChange(boolean selfChange) {
                        synchronized (mLock) {
        //Step:4
                            updateBatteryWarningLevelLocked();
                        }
                    }
                };
                final ContentResolver resolver = mContext.getContentResolver();
                resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
                        false, obs, UserHandle.USER_ALL);
                updateBatteryWarningLevelLocked();
            }
        }
    }
    1. 电池属性变更监听事件,调用update更新电池信息;
    1. 对其他service或者app应用提供BinderService服务,以及对系统进程提供LocalService本地服务
  • 3.当ActivityManager启动完成的时候,回调onBootPhase方法,BatterService才可以对外发送Intent
  • 4.更新一些低电量提示内容,比如 15%低电量;

4.处理电池属性变化事件

 private void updateBatteryWarningLevelLocked() {
      ........
        processValuesLocked(true);
    }
 private void processValuesLocked(boolean force) {
        boolean logOutlier = false;
        long dischargeDuration = 0;

        mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
    //Step:1
        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;
        }
      .....
     //Step:2
        try {
            mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
                    mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
                    mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter,
                    mBatteryProps.batteryFullCharge);
        } catch (RemoteException e) {
            // Should never happen.
        }
      ......
     //Step:3
    shutdownIfNoPowerLocked();
        shutdownIfOverTempLocked();
        .......
        //Step:4
            sendIntentLocked();
            mLed.updateLightsLocked();
}
  • 1.根据底层提供的电池数据,判断当前手机的充电状态:充电状态、USB连接、无线充电状态、未充电状态;
  • 2.电池属性改变的时候,会将全部信息写到mBatteryStats中,app端从mBatteryStats中获取当前电池的电量以及状态;
  • 3.电量0%,以及高温关机(默认68度);
  • 4.发送电池状态的持续性广播,例如电量、电压、充电模式等;并更新LED灯颜色;

低电量关机
如果电池电量严重不足,或没有电,发起关机。

 private void shutdownIfNoPowerLocked() {

        if (mBatteryProps.batteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mActivityManagerInternal.isSystemReady()) {
                        Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
                        intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
                    }
                }
            });
        }
    }

高温关机
如果温度过高,则优雅地关闭(默认为> 68.0C),启动关机画面

private void shutdownIfOverTempLocked() {
        if (mBatteryProps.batteryTemperature > mShutdownBatteryTemperature) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mActivityManagerInternal.isSystemReady()) {
                        Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
                        intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
                    }
                }
            });
        }
    }

下面我们使用流程图来总结下BatteryService服务processValueLocked方法的处理流程。


image.png

二、疑问

电池属性改变的时候,为什么要将全部信息传递到mBatteryStats中?
IBatteryStats的实现类是BatteryStatsImpl,BatteryStatsImpl继承自BatteryStats,BatteryStats可以被app获取到,它的setBatteryState()方法会将电池属性写到历史记录,并且计算了电池的已用时间和可用时间,这样,当我们需要用到电池信息的时候,就可以先获取到当前的BatteryStats,然后再从BatteryStats中获取电池属性;

从上面可以看出,app端既可以从广播得到电池的当前属性,还可以通过BatteryStats得到电池的当前属性;
BatteryService既通过广播的方式将信息发送给观察者,也提供了接口供外界调用。

相关文章

网友评论

      本文标题:第八章:BatteryService

      本文链接:https://www.haomeiwen.com/subject/kzhwuhtx.html