Android7.0 BatteryService

BatteryService与PMS之间的关系比较密切,提供接口用于获取电池信息、充电状态等。 
为了对Android的功耗控制有更深入的了解,我们有必要分析一下BatteryService。

一、启动过程 
BatteryService与系统中的许多服务一样,是由SystemServer启动的。 
我们一起看看SystemServer中相关的代码:

..............
//PMS是在startBootstrapServices中创建的
startBootstrapServices();
//BatteryService在startCoreServices中创建的
startCoreServices();
..............
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

跟进一下startCoreServices:

private void startCoreServices() {
    mSystemServiceManager.startService(BatteryService.class);
    ..................
}
  • 1
  • 2
  • 3
  • 4

之前的博客分析过SystemServiceManager的startService方法。 
该方法主要通过反射的方式创建出对应的服务, 
然后,将服务保存在SystemServiceManager的mServices变量中, 
最后,调用服务对应的onStart方法。

我们不再赘述SystemServiceManager固有启动服务的流程,直接来看看本篇博客的主角BatteryService相关的代码。

1、BatteryService的构造函数

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

    mContext = context;
    mHandler = new Handler(true /*async*/);

    //内部类Led,控制不同电量下led灯的颜色
    mLed = new Led(context, getLocalService(LightsManager.class));

    //电量统计服务
    mBatteryStats = BatteryStatsService.getService();

    //以下是根据配置文件,定义不同电量对应的等级

    //电池危急的电量;当电池电量低于此值时,将强制关机
    mCriticalBatteryLevel = mContext.getResources().getInteger(
            com.android.internal.R.integer.config_criticalBatteryWarningLevel);

    //低电警告的电量;当电池电量低于此值时,系统报警,例如闪烁LED灯等
    mLowBatteryWarningLevel = mContext.getResources().getInteger(
            com.android.internal.R.integer.config_lowBatteryWarningLevel);

    //关闭低电警告的电量;当电池电量高于此值时,结束低电状态,停止警示灯
    mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
            com.android.internal.R.integer.config_lowBatteryCloseWarningBump);

    //这里定义的不再是电量,而是关闭电池的温度(温度失控,就会出现三星S7爆炸啥的......)
    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()) {
        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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

从上面的代码可以看出,整体来看BatteryService构造函数是比较简单的,主要的目的就是得到一些变量。

2、onStart函数 
接下来我们看看BatteryService的onStart函数:

public void onStart() {
    //获取电源属性服务的BinderProxy对象
    //电源属性服务运行在android的healthd进程中
    //对应文件为system/core/healthd/BatteryPropertiesRegistrar.cpp
    //这个写法确实很风骚,java层通过Binder直接与native层通信
    IBinder b = ServiceManager.getService("batteryproperties");
    final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
            IBatteryPropertiesRegistrar.Stub.asInterface(b);
    try {
        //向电源属性服务注册一个回调接口
        //当电源属性发生变化时,BatteryListener的batteryPropertiesChanged函数将被调用
        batteryPropertiesRegistrar.registerListener(new BatteryListener());
    } catch (RemoteException e) {
        // Should never happen.
    }

    mBinderService = new BinderService();
    //与PMS等很多系统服务一样,将自己注册到service manager进程中
    publishBinderService("battery", mBinderService);

    //之前介绍PMS时,提到过这个函数
    //对于基于LocalServices管理的对象而言,这个函数调用相当于单例模式的进阶版
    //以后BatteryManagerInternal接口类型的对象,只能有BatteryService的内部类LocalService一个
    publishLocalService(BatteryManagerInternal.class, new LocalService());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

从以上代码可以看出,BatteryService在onStart函数中主要完成一些服务注册、接口注册的工作。

2.1 BatteryPropertiesRegistrar服务 
我们看看BatteryPropertiesRegistrar.h的定义:

.......
namespace android {

class BatteryPropertiesRegistrar : public BnBatteryPropertiesRegistrar,
                                   public IBinder::DeathRecipient {
public:
    void publish(const sp<BatteryPropertiesRegistrar>& service);
    void notifyListeners(struct BatteryProperties props);
............
}

};  // namespace android
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

再看看BatteryPropertiesRegistrar.cpp中我们目前关注的函数:

namespace android {

void BatteryPropertiesRegistrar::publish(
    const sp<BatteryPropertiesRegistrar>& service) {
    //注册服务到service manager进程
    defaultServiceManager()->addService(String16("batteryproperties"), service);
}

void BatteryPropertiesRegistrar::notifyListeners(struct BatteryProperties props) {
    Mutex::Autolock _l(mRegistrationLock);
    for (size_t i = 0; i < mListeners.size(); i++) {
        //通知观察者
        mListeners[i]->batteryPropertiesChanged(props);
    }
}

void BatteryPropertiesRegistrar::registerListener(const sp<IBatteryPropertiesListener>& listener) {
    {
        if (listener == NULL)
            return;
        Mutex::Autolock _l(mRegistrationLock);
        // check whether this is a duplicate
        for (size_t i = 0; i < mListeners.size(); i++) {
            if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) {
                return;
            }
        }

        //存储观察者
        mListeners.add(listener);
        IInterface::asBinder(listener)->linkToDeath(this);
    }
    //更新底层的电源状态,最终将调用到BatteryMonitor.cpp的update函数
    //也是BatteryService第一次启动,注册Listener后,立马就会更新一次电源信息
    healthd_battery_update();
}
..........
}  // namespace android
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

这里我们不展开native层healthd_battery_update的流程,主要是从大量的文件中读取电源的信息,有兴趣的朋友可以进一步研究一下。 
此处,我们仅思考一下这种Java层和native层的Binder通信过程。

我们见过太多对等的Binder通信结构,即双方的主体均在native层,或都在Java层。 
这是第一次看到客户端在Java层,服务端在native层。

其实仔细想想,这是完全符合Binder通信架构的。 
对于客户端而言,它只需要从service manager进程获取到服务端的BpBinder值,然后利用这个BpBinder值逐步构成Java层的BinderProxy对象(会进一步转化为基于业务的服务代理)。 
客户端根本就不要求服务端具有Java层的结构。在实际的通信过程中,客户端数据通过Binder驱动,传到服务端的native层。若native层就能够完成处理过程,就不需要往Java层作进一步的传输,直接返回结果即可。整个处理过程,对于客户端而言,完全是透明的。

2.2 回调接口的作用 
第一次看到这样的通信用法,扯的有点远了。 
我们回过头来看一下BatteryListener的回调接口:

private final class BatteryListener extends IBatteryPropertiesListener.Stub {
    @Override public void batteryPropertiesChanged(BatteryProperties props) {
        final long identity = Binder.clearCallingIdentity();
        try {
            //电源属性发生变化后,回调BatteryService的update函数
            BatteryService.this.update(props);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

BatteryService的update函数定义如下:

private void update(BatteryProperties props) {
    synchronized (mLock) {
        //从代码来看,mUpdatesStopped默认为false,通过shell command才有可能改变
        if (!mUpdatesStopped) {
            mBatteryProps = props;
            // Process the new values.
            //更新电源相关的信息,后文详细介绍
            processValuesLocked(false);
        } else {
            mLastBatteryProps.set(props);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

易于看出,BatteryService注册回调接口的作用是:更新其维护的电源信息。

二、onBootPhase 
除去上述的基本启动过程外,还需要关注一下BatteryService的onBootPhase函数。

1、基础知识 
以前分析系统服务时,忽视了这个接口,现在借此机会补充一下此处的知识。 
在SystemServiceManager中提供了以下接口:

/**
* Starts the specified boot phase for all system services that have been started up to
* this point.
*
*/
public void startBootPhase(final int phase) {
    ..............
    mCurrentPhase = phase;
    ..............
    try {
        .............
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            //前面的博客已经分析过,SystemServer利用SystemServiceManager启动的系统服务
            //均会保留在mServices中
            final SystemService service = mServices.get(i);
            try {
                //调用此时已经加入的service的onBootPhase函数
                service.onBootPhase(mCurrentPhase);
            } catch (Exception ex) {
                ............
            }
        }
    } finally {
        .............
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

SystemServiceManager的startBootPhase函数中的参数,对应于系统启动的不同阶段。 
详细的定义在SystemService.java中:

/*
* Boot Phases
*/
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;

/**
* After receiving this boot phase, services can obtain lock settings data.
*/
public static final int PHASE_LOCK_SETTINGS_READY = 480;

/**
* After receiving this boot phase, services can safely call into core system services
* such as the PowerManager or PackageManager.
*/
public static final int PHASE_SYSTEM_SERVICES_READY = 500;


/**
* After receiving this boot phase, services can broadcast Intents.
*/
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

/**
* After receiving this boot phase, services can start/bind to third party apps.
* Apps will be able to make Binder calls into services at this point.
*/
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

/**
* After receiving this boot phase, services can allow user interaction with the device.
* This phase occurs when boot has completed and the home application has started.
* System services may prefer to listen to this phase rather than registering a
* broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
*/
public static final int PHASE_BOOT_COMPLETED = 1000;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

以上是原生定义的系统启动的不同阶段。

这么做的目的是: 
SystemServer会依次启动许多服务,但服务之间的功能是相互依赖的。 
因此,每个服务刚被启动时,都完成最基本的初始化。

当系统运行到某个阶段后,调用SystemServiceManager的startBootPhase函数, 
于是所有的服务都可以进一步完成这个阶段可以进行的初始化工作。

通过这种方式,每个服务的初始化过程可以按阶段分为好几个部分,增加了不同阶段的初始化工作的清晰度; 
同时,每个阶段调用startBootPhase函数,就像一种同步机制一样,让所有服务的初始化进程保持一致的步调。

我们按照先后顺序,看看每个阶段对应的代码: 
在SystemServer的startBootstrapServices方法中:

private void startBootstrapServices() {
    ..............
    // We need the default display before we can initialize the package manager.
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    ..............
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在SystemServer的startOtherService方法中:

private void startOtherServices() {
    ................
    // Needed by DevicePolicyManager for initialization
    mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);

    mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
    .................
    mActivityManagerService.systemReady(new Runnable() {
        @Override
        public void run() {
            ............
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
            ............
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
            ................
        }
    });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在ActivityManagerService的finishBooting函数中:

final void finishBooting() {
    ..........
    // Let system services know.
    mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
    ..........
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

需要注意的是,不是每个服务都需要将初始化过程拆解成不同的部分,按需进行对应的实现即可。

2、BatteryService的onBootPhase 
有了以上的知识,我们回过头来看一下BatteryService的onBootPhase函数:

public void onBootPhase(int phase) {
    //BatteryService只需要在PHASE_ACTIVITY_MANAGER_READY后,在进行部分的初始化即可
    //其它的服务也是通过这种方式,按需实现阶段化的初始化
    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) {
                        updateBatteryWarningLevelLocked();
                    }
                }
            };
            final ContentResolver resolver = mContext.getContentResolver();
            //监听设置中低电量警告的电量值是否改变,改变时调用updateBatteryWarningLevelLocked函数
            resolver.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
                    false, obs, UserHandle.USER_ALL);

            updateBatteryWarningLevelLocked();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

从上面的代码可以看出,BatteryService的onBootPhase函数主要是注册一个监听器,检测低电量警告的电量值是否改变,然后调用updateBatteryWarningLevelLocked函数。

接下来,我们就一起看看updateBatteryWarningLevelLocked的主要功能。

private void updateBatteryWarningLevelLocked() {
    final ContentResolver resolver = mContext.getContentResolver();

    //获取XML中配置的默认警告电量值
    int defWarnLevel = mContext.getResources().getInteger(
            com.android.internal.R.integer.config_lowBatteryWarningLevel);

    //获取设置中用户定义的电量警告值
    mLowBatteryWarningLevel = Settings.Global.getInt(resolver,
            Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);

    //用户没有定义,则使用默认的
    if (mLowBatteryWarningLevel == 0) {
        mLowBatteryWarningLevel = defWarnLevel;
    }

    //警告值不能低于危险值
    if (mLowBatteryWarningLevel < mCriticalBatteryLevel) {
        mLowBatteryWarningLevel = mCriticalBatteryLevel;
    }

    //计算出关闭警告的电量值
    mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
            com.android.internal.R.integer.config_lowBatteryCloseWarningBump);

    //更新电池信息 (前面已提到,注册的接口回调时也会调用该函数)
    processValuesLocked(true);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

可以看出updateBatteryWarningLevelLocked函数主要关注低电提醒相关的变量更新,然后将剩余的工作交给processValuesLocked处理。

三、processValuesLocked主要功能 
我们跟进一下processValuesLocked函数:

//force表示是否强制更新信息
//当force为false时,只有新旧信息不一致才更新
private void processValuesLocked(boolean force) {
    ...........
    //判断当前电量是否危险;mBatteryProps由电源属性服务提供
    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 {
        //将信息递交给电源统计服务,我们介绍BatteryStatsService时,再分析该函数
        mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
                mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
                mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter);
    } catch (RemoteException e) {
        // Should never happen.
    }

    //电池电量低(batteryLevel==0)且未充电时,拉起关机对话框
    shutdownIfNoPowerLocked();

    //电池温度过高(默认为68C),拉起关机对话框
    shutdownIfOverTempLocked();

    //强制更新,或电源相关属性发生变化时,进行对应操作
    //这段代码真的是没法不吐槽,Google难道不能重写一下BatteryProperties的equals方法
    //Effective Java
    if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
            mBatteryProps.batteryHealth != mLastBatteryHealth ||
            mBatteryProps.batteryPresent != mLastBatteryPresent ||
            mBatteryProps.batteryLevel != mLastBatteryLevel ||
            mPlugType != mLastPlugType ||
            mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
            mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
            mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent ||
            mBatteryProps.maxChargingVoltage != mLastMaxChargingVoltage ||
            mBatteryProps.batteryChargeCounter != mLastChargeCounter ||
            mInvalidCharger != mLastInvalidCharger)) {

        //充电状态发生变化(不关注充电的方式,即usb变为AC之类的,只是关注充电变为未充电等事件)
        if (mPlugType != mLastPlugType) {
            if (mLastPlugType == BATTERY_PLUGGED_NONE) {
                // discharging -> charging

                // There's no value in this data unless we've discharged at least once and the
                // battery level has changed; so don't log until it does.
                //记录一下不充电待机的情况下,耗电量及耗电时长
                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){
                // charging -> discharging or we just powered up

                //本次充电结束,重新开始计算耗电情况,于是初始化下面的变量
                mDischargeStartTime = SystemClock.elapsedRealtime();
                mDischargeStartLevel = mBatteryProps.batteryLevel;
            }
        }

        //以下是记录电源的状态信息、电量信息
        if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
                mBatteryProps.batteryHealth != mLastBatteryHealth ||
                mBatteryProps.batteryPresent != mLastBatteryPresent ||
                mPlugType != mLastPlugType) {
            EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
                    mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0,
                    mPlugType, mBatteryProps.batteryTechnology);
        }
        if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
            // Don't do this just from voltage or temperature changes, that is
            // too noisy.
            EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
                    mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
        }

        //电池电量低到危险的程度,且没充电,记录耗电时间
        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?
            // 当前未充电,且当前电量小于提醒电量,设置低电量为true
            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;
            }
        }

        //发送广播ACTION_BATTERY_CHANGED,内含电源当前的全部信息
        sendIntentLocked();

        //单独发送一些广播信息:
        //通知进入充电状态,或离开充电状态
        //通知电源进入低电模式,或离开低电模式
        ..............

        // Update the battery LED
        // 根据电源的电量和状态,改变LED灯的颜色
        mLed.updateLightsLocked();

        // This needs to be done after sendIntent() so that we get the lastest battery stats.
        if (logOutlier && dischargeDuration != 0) {
            //利用BatteryInfoService记录耗电情况的dump文件
            logOutlierLocked(dischargeDuration);
        }

        //更新本地变量
        ....................
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147

这一部分代码其实没什么太大的难度,就是写的比较繁琐。 
我们还是画个图整理一下: 

总结 
从BatteryService整个代码结构来看,我们大致了解到BatterySerivce负责与native层通信,更新fwk中维护的电源信息。 
BatteryService既通过广播的方式将信息发送给观察者,也提供了接口供外界调用。 
同时,BatteryService提供的信息,应该是BatteryStatsService统计的重要依据。

猜你喜欢

转载自blog.csdn.net/AndroidBBC/article/details/78520805