美文网首页
电源 | Battery系列(一) BatteryService

电源 | Battery系列(一) BatteryService

作者: 力卉编程 | 来源:发表于2019-12-28 16:51 被阅读0次

    BatteryService负责监听充电状态和电量变化,当电量值或者充电类型改变时,会获取到底层healthd上报的电池状态信息,并更新到BatteryStatsService中进行统计,同时会将这些值存储到Intent中,以广播的形式发送到监听了ACTION_BATTERY_CHANGED的组件中,其他组建可以通过Intent.getExtra()的方式获取到电池信息。

    1.BatteryService的启动流程
    BatteryService继承于SyetemService,SyetemService是所有系统服务的基类,每个SyetemService的启动流程都具有相同的步骤,他们实现并重写其父类方法。因此,在分析BatteryService之前,先看看SystemServer的启动相关方法。SystemServer启动时调用方法如下,并且都是在SystemServer的main线程中运行:

    1.Constructor():构造方法,通过反射的方式调用;
    2.onStart():开始运行服务;
    3.onBootPhase(int):该方法表示启动阶段,会根据不同的参数(阶段)调用多次,直到PHASE_BOOT_COMPLETED阶段调用后不再调用,表示启动完成,对于每个阶段,可以完成特定的工作;
    了解了上述内容后,着手分析BatteryService就容易多了,首先,BatteryService会在SystemServer中进行启动:

    /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
    private void run() {
        ......
    // Start services.
        try {
        //启动引导服务
            startBootstrapServices();
        //启动核心服务
            startCoreServices();
        //启动其他服务
            startOtherServices();
        //关闭启动线程池
            SystemServerInitThreadPool.shutdown();
        ......
        } catch (Throwable ex) {
            throw ex;
        } finally {
            traceEnd();
        }
    }
    

    startBootstrapServices()中启动的是一些依赖性比较高的系统服务(所以方法名为"引导服务"),如PMS就是在这里进行启动的。
    startCoreServices()中启动一些核心服务,从代码中看,启动的核心服务有四种,其中就包括要分析的BatteryService。
    startOtherServices()用来启动其他的一些服务。

    在startCoreServices()中,通过SystemServiceManager中的方法,传入类名作为参数,利用反射机制对BatteryService进行实例化:

    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            ......
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) 
            }
            startService(service);
            return service;
        } finally {
        }
    }
    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        long time = SystemClock.elapsedRealtime();
        try {
            //调用onStart()方法开启服务
            service.onStart();
        } catch (RuntimeException ex) {
        }
    }
    

    分析到这一步,SystemServive的生命周期方法就剩下onBootPhase()方法了,这个方法也说过了,是负责启动启动服务的过程中分阶段进行一些工作的,也运行在SystemServer的main线程中:

    private void startOtherServices() {
        ......
        mSystemServiceManager.startBootPhase(
              SystemService.PHASE_LOCK_SETTINGS_READY);
        mSystemServiceManager.startBootPhase(
              SystemService.PHASE_SYSTEM_SERVICES_READY);
        mSystemServiceManager.startBootPhase(
                  SystemService.PHASE_ACTIVITY_MANAGER_READY);
        mSystemServiceManager.startBootPhase(
                  SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
        mSystemServiceManager.startBootPhase(
                  SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
        ......
     }
    public void startBootPhase(final int phase) {
        ......
        mCurrentPhase = phase;
        try {
            final int serviceLen = mServices.size();
            for (int i = 0; i < serviceLen; i++) {
                final SystemService service = mServices.get(i);
                long time = SystemClock.elapsedRealtime();
                try {
                    service.onBootPhase(mCurrentPhase);
                } catch (Exception ex) {
                }
            }
        } finally {
        }
    }
    

    到这里,SystemServer中启动BatteryService相关的内容就完毕了,现在依次看看在SystemServer中启动时,BatteryService中的构造方法、onStart()方法、onBootPhase()方法中都做了些什么。

    1.1.Constructor()
    首先看调用构造方法时的处理,在BatteryService中:

    public BatteryService(Context context) {
        super(context);
        mContext = context;
        mHandler = new Handler(true /*async*/);
        //电源呼吸灯
        mLed = new Led(context, getLocalService(LightsManager.class));
        //BatteryStatsService服务,用于统计服务
        mBatteryStats = BatteryStatsService.getService();
        //AMS本地服务
        mActivityManagerInternal = 
                LocalServices.getService(ActivityManagerInternal.class);
        //电量警告值,该值为5
        mCriticalBatteryLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_criticalBatteryWarningLevel);
        //低电量警告值,该值为15
        mLowBatteryWarningLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryWarningLevel);
        //关闭低电量警告的值,为20
        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + 
                mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
        //高温关机的温度值,该值为68C
        mShutdownBatteryTemperature = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_shutdownBatteryTemperature);
        //设置UEvents监听,监听kernel层上传的无效charge信息
        // 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");
        }
    }
    

    在构造方法中,详细信息都进行了注释,这里有两点需重点说明一下,先看第一点:初始化了mBatteryStats,该对象类型为IBatteryStats,这里使用了Binder机制,在分析BatteryStatsService时将会知道,BatteryStatsService继承于IBatteryStats.Stub,因此,可以把BatteryStatsService作为Binder的服务端来使用,接着来看一下BatteryStatsService的getService()方法:

    public static IBatteryStats getService() {
        if (sService != null) {
            return sService;
        }
        IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
        sService = asInterface(b);
        return sService;
    }
    

    通过ServiceManager.getService(String)获取了一个IBinder对象,并将IBinder对象转换为客户端需要的类型返回;如此一来,BatteryService中就获取到了IBatteryStats接口,从而可以和BatteryStatsService进行交互。

    再分析第二点:UEvent机制。UEvent是kernel通知用户空间的一种机制,很多地方都用到了UEvent机制,如USB插拔/充电等,其本质是内核发送一个字符串(可通过Socket),应用层接受并解释该字符串,获取相应信息,如果信息有变化,onUEevent()触发,做出改变。
    使用该机制时,需要一个UEventObserver对象,并重写onUEvent(UEvent e)方法,然后调用startObserving()进行监听,当一个uevent匹配startObserving(String)中指定的string时触发onUEvent();

    1.2.onStart()
    到这时,BatteryService的构造方法分析完毕了,根据启动流程,接下来执行的是第二步,onStart()方法,如下:

    @Override
    public void onStart() {
        //获取注册时名为“batteryproperties”的服务
        IBinder b = ServiceManager.getService("batteryproperties");
        final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
                IBatteryPropertiesRegistrar.Stub.asInterface(b);
        try {
            batteryPropertiesRegistrar.registerListener(new BatteryListener());
        } catch (RemoteException e) {
            // Should never happen.
        }
        mBinderService = new BinderService();
        //发布Binder服务
        publishBinderService("battery", mBinderService);
        //发布本地服务
        publishLocalService(BatteryManagerInternal.class, new LocalService());
    }
    

    在onStart()中,首先获取了一个“batterypropeties”的Binder,也即IBatteryPropertiesRegistrar,这个服务由healthd层进行注册,底层每间隔1分钟,会通过这个服务将电池状态信息更新给BatteryService.
    然后,实例化了内部类BinderService,该类继承自Binder,然后将这个Binder通过publishBinderService()发布到了系统服务中,就像之前分析PowerManagerService一样,目的是可以通过getSystemService(String)来获取其实例。
    publishLocalService()方法中将BatteryService的内部类LocalService注册到了本地服务中,LocalService中提供了一些getxxx()获取电池相关的方法,且仅限于SystemServer进程内使用。

    1.3.onBootPhase()
    onStart()方法调用之后,开始调用onBootPhase()方法:

    @Override
    public void onBootPhase(int phase) {
        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();
                resolver.registerContentObserver(Settings.Global.getUriFor(
                        Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
                        false, obs, UserHandle.USER_ALL);
                updateBatteryWarningLevelLocked();
            }
        }
    }
    

    在这个方法中,设置了一个ContentObverser观察者,当Settings.Global中低电量触发值改变时,就会触发onChange()方法。根据上面分析,再分析updateBatteryWarningLevelLocked()方法:

    private void updateBatteryWarningLevelLocked() {
        final ContentResolver resolver = mContext.getContentResolver();
        //获取配置文件中存储的低电量触发默认值,15
        int defWarnLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryWarningLevel);
        //获取Settings.Global中存储的低电量触发值
        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);
    }
    

    这个方法中更新了低电量警告值和关闭低电量警告的值,在资源文件中定义的值如下:

    <!-- Display low battery warning when battery level dips to this value -->
    <integer name="config_lowBatteryWarningLevel">15</integer>
    <!-- Close low battery warning when battery level reaches the lowBatteryWarningLevel plus this -->
    <integer name="config_lowBatteryCloseWarningBump">5</integer>
    

    从以上内容可知,默认情况下,当电量达到15%时会弹出低电量提示。

    在上述方法的最后,调用了processValuesLocked()方法,它是BatteryService中最核心的方法,因此这里从启动流程中分离出来,单独进行分析。
    2.processValuesLocked()
    processValuesLocked()是BatteryService中更新电池信息最核心的方法,当healthd从kernel层获取电池信息后,会上报给BatteryService,BatteryService中通过这个方法进行处理从而完成更新。

    在BatteryService中,有三个地方调用了processValuesLocked():

    1.启动BatteryService时,在onBootPhase()方法中的updateBatteryWarningLock()方法中;
    2.在healthd层向BatteryService更新电池状态信息的update()方法中,这里会每分钟调用一次;
    3.通过adb shell命令dump时在processValuesFromShellLocked()中。
    由于该方法体较大,因此分段来进行分析:
    2.1.获取充电类型

    mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
    //获取充电类型
    if (mBatteryProps.chargerAcOnline) {
        //AC充电
        mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
    } else if (mBatteryProps.chargerUsbOnline) {
        //USB充电
        mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
    } else if (mBatteryProps.chargerWirelessOnline) {
        //无线充电
        mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
    } else {
        //没有充电
        mPlugType = BATTERY_PLUGGED_NONE;
    }
    

    2.2.更新统计电池状态信息

    try {
        //将电池信息交给BatteryStatsService进行统计
        mBatteryStats.setBatteryState(mBatteryProps.batteryStatus,
                mBatteryProps.batteryHealth,
                mPlugType, mBatteryProps.batteryLevel, 
                mBatteryProps.batteryTemperature,
                mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter,
                mBatteryProps.batteryFullCharge);
    } catch (RemoteException e) {
        // Should never happen.
    }
    

    这里将BatteryProperties中最新的电池信息更新到了BatteryStatsService中进行统计;BatteryProperties是由healthd中传入,实现了Parcelable接口,里面存储了healthd中从节点文件中读取的电池信息。

    2.3.进行低电量时和高温时的关机

    //低电量关机
    shutdownIfNoPowerLocked();
    //高温关机
    shutdownIfOverTempLocked();
    

    当电量为0并且没有充电时,会自动关机;当电池温度高于68C时,也会进行自动关机;

    2.4.充电类型改变时获取放电时长和放电量

    //充电类型改变
    if (mPlugType != mLastPlugType) {
        //上次没充电,说明设备由放电进入充电状态
        if (mLastPlugType == BATTERY_PLUGGED_NONE) {
            /**
             * mDischargeStartTime默认为0,在充电进入放电时赋值为当前时间,放电进入
             *充电时又赋值为0
             * mDischargeStartLevel为开始放电时的电量
             * mDischargeStartTime != 0说明有一次充电->放电
             * mDischargeStartLevel!=mBatteryProps.batteryLevel说明电池电量有改变
             */
            if (mDischargeStartTime != 0 && mDischargeStartLevel != 
                           mBatteryProps.batteryLevel) {
                //放电时间段 = 当前时间 - 开始放电时间
                dischargeDuration = SystemClock.elapsedRealtime() - 
                           mDischargeStartTime;
                //重新赋值为0
                mDischargeStartTime = 0;
            }
        } else if (mPlugType == BATTERY_PLUGGED_NONE) {//放电->充电
            // charging -> discharging or we just powered up
            //重新赋值为当前时间
            mDischargeStartTime = SystemClock.elapsedRealtime();
            //重新赋值为当前电量
            mDischargeStartLevel = mBatteryProps.batteryLevel;
        }
    }
    

    2.5.更新低电量临界值

    //mBatteryLevelLow表示当前电量是否小于等于低电量警告值
    if (!mBatteryLevelLow) {
        // Should we now switch in to low battery mode?
        //没充电且当前电量小于等于15%
        if (mPlugType == BATTERY_PLUGGED_NONE
                && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
            mBatteryLevelLow = true;
        }
    } else {
        //充电时mBatteryLevelLow置为false,退出低电量模式
        if (mPlugType != BATTERY_PLUGGED_NONE) {
            mBatteryLevelLow = false;
            //电量到达20%,退出低电量模式
        } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel)  {
            mBatteryLevelLow = false;
            //force为true时进行强制更新
        } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
            mBatteryLevelLow = false;
        }
    }
    

    mBatteryLevelLow是一个用于判断当前电量是否小于低电量警告值的bool值,和低电量模式有关,在PMS中设置低电量模式时,都会通过LocalService获取到这个值。

    2.6.发送充电/放电广播和到达低电量/退出低电量广播

    /**
     *放电->充电,发送Intent.ACTION_POWER_CONNECTED广播,mSequence每次都会+1,
     *用于记录广播次序,和JobScheduler有关
     *
     *充电->放电,发送Intent.ACTION_POWER_DISCONNECTED广播
     */
    if (mPlugType != 0 && mLastPlugType == 0) {
        final Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
        statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_
                         ONLY_BEFORE_BOOT);
        statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
            }
        });
    }
    else if (mPlugType == 0 && mLastPlugType != 0) {
        final Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
        statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_
               BEFORE_BOOT);
        statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
            }
        });
    }
    /**
     * 发送电池电量过低广播Intent.ACTION_BATTERY_LOW,该广播在两种情况下发送:
     * 1.设备由充电进入放电(拔掉充电器)后,电量小于15%
     * 2.设备在放电过程中,电量小于15%
     *
     * 当电量达到20%时,发送电池状态正常广播Intent.ACTION_BATTERY_OKAY
     */
    if (shouldSendBatteryLowLocked()) {
        mSentLowBatteryBroadcast = true;
        final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
        statusIntent.setFlags(Intent.
                       FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
            }
        });
    } else if (mSentLowBatteryBroadcast &&
            mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
        mSentLowBatteryBroadcast = false;
        final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
        statusIntent.setFlags(Intent.
                       FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
            }
        });
    }
    

    2.7.调用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_SEQUENCE, mSequence);
        intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
        intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
        intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
        intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
        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() {
                ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
            }
        });
    }
    

    在该方法中,发送了Action为Intent.ACTION_BATTERY_CHANGED的粘性广播,并将所有电池信息存储到Intent中,当BroadcastReceiver接收到后,就可以从中获取到电池信息

    2.8.更新LED灯状态

    mLed.updateLightsLocked();
    public void updateLightsLocked() {
            final int level = mBatteryProps.batteryLevel;
            final int status = mBatteryProps.batteryStatus;
            //电量<15%
            if (level < mLowBatteryWarningLevel) {
                //电池状态处于充电状态
                if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
                    // Solid red when battery is charging
                    mBatteryLight.setColor(mBatteryLowARGB);
                } else {
                    // Flash red when battery is low and not charging
                    mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED,
                            mBatteryLedOn, mBatteryLedOff);
                }
                //电池状态处于充电状态||满电量状态
            } else if (status == BatteryManager.BATTERY_STATUS_CHARGING
                    || status == BatteryManager.BATTERY_STATUS_FULL) {
                //处于满电亮状态,或者电量大于90%
                if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) {
                    // Solid green when full or charging and nearly full
                    mBatteryLight.setColor(mBatteryFullARGB);
                } else {//电量小于90且充电
                    // Solid orange when charging and halfway full
                    mBatteryLight.setColor(mBatteryMediumARGB);
                }
            } else {//不处于充电状态
                // No lights if not charging and not low
                mBatteryLight.turnOff();
            }
        }
    }
    

    2.9.更新电池信息

    mLastBatteryStatus = mBatteryProps.batteryStatus;
    mLastBatteryHealth = mBatteryProps.batteryHealth;
    mLastBatteryPresent = mBatteryProps.batteryPresent;
    mLastBatteryLevel = mBatteryProps.batteryLevel;
    mLastPlugType = mPlugType;
    mLastBatteryVoltage = mBatteryProps.batteryVoltage;
    mLastBatteryTemperature = mBatteryProps.batteryTemperature;
    mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent;
    mLastMaxChargingVoltage = mBatteryProps.maxChargingVoltage;
    mLastChargeCounter = mBatteryProps.batteryChargeCounter;
    mLastBatteryLevelCritical = mBatteryLevelCritical;
    mLastInvalidCharger = mInvalidCharger;
    

    至此,BatteryService的启动流程和核心方法就就分析完毕,现在剩余其内部类BatteryListener了。
    3.BatteryService.BatteryListener
    在分析BatteryService的启动过程时,对onstart()方法中的IBatteryPropertiesRegistrar和BatteryListener没有深入的分析说明,现在主要研究他们之间的关系和作用。

    回到onStart()方法中:

    @Override
    public void onStart() {
        //获取名为“batteryproperties”的服务
        IBinder b = ServiceManager.getService("batteryproperties");
        final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
                IBatteryPropertiesRegistrar.Stub.asInterface(b);
        try {
            batteryPropertiesRegistrar.registerListener(new BatteryListener());
        } catch (RemoteException e) {
            // Should never happen.
        }
        ......
    }
    

    首先,会在系统服务中获取“batteryproperties”注册的服务,获取到的对象为Binder,那么这个名为“batteryproperties”的系统服务,它是在何处进行注册的呢?
    我在Java代码中搜索后,没有发现对应的注册代码,难不成它没有进行注册?这是不可能的。经过全局搜索发现了其注册位置,在c++代码中,路径为:\system\core\healthd\BatteryPropertiesRegistrar.cpp.

    void BatteryPropertiesRegistrar::publish(
        const sp<BatteryPropertiesRegistrar>& service) {
        defaultServiceManager()->addService(String16("batteryproperties"), service);
    }
    

    这里涉计到了Healthd相关东西,在之后的文章中进行分析。
    之后对IBatteryPropertiesRegistrar 注册一个监听事件,当监听内容改变时回调对应方法,监听器如下:

    //healthd中每间隔1分钟上报一次,该方法也会进行回调
    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);
            }
       }
    }
    

    可以看到,BaytteryListener继承于IBatteryPropertiesListener.Stub,因此也是一个Binder对象;当监听内容发生变化时,回调方法batteryPropertiesChanged()中调用update(BatteryProperties)方法:

    private void update(BatteryProperties props) {
        synchronized (mLock) {
            if (!mUpdatesStopped) {
                mBatteryProps = props;
                // Process the new values.
                processValuesLocked(false);
            } else {
                mLastBatteryProps.set(props);
            }
        }
    }
    

    在这个方法中,通过监听器传入的BatteryProperties初始化了成员变量mBatteryProps 。BatteryProperties中带有电池状态信息,通过该方法最终调用了processValuesLocked(false)方法,从而完成电池状态信息的更新。

    4.电池信息状态及其属性值
    充电类型:

    字段 值 含义
    BATTERY_PLUGGED_NONE 0 没有充电
    BATTERY_PLUGGED_AC 1 AC充电
    BATTERY_PLUGGED_USB 2 USB充电
    BATTERY_PLUGGED_WIRELESS 4 无线充电
    BATTERY_PLUGGED_ANY 7 除BATTERY_PLUGGED_NONE外以上
    充电状态:

    字段 值 含义
    BATTERY_STATUS_UNKNOWN 1 未知
    BATTERY_STATUS_CHARGING 2 正在充电
    BATTERY_STATUS_DISCHARGING 3 放电中
    BATTERY_STATUS_NOT_CHARGING 4 没有充电
    BATTERY_STATUS_FULL 5 电充满了
    健康状态:

    字段 值 含义
    BATTERY_HEALTH_UNKNOWN 1 未知
    BATTERY_HEALTH_GOOD 2 良好
    BATTERY_HEALTH_OVERHEAT 3 过热
    BATTERY_HEALTH_DEAD 4 没电
    BATTERY_HEALTH_OVER_VOLTAGE 5 电压过高
    BATTERY_HEALTH_UNSPECIFIED_FAILURE 6 未知
    BATTERY_HEALTH_COLD 7 过冷

    完~~~
    文 |力卉编程

    相关文章

      网友评论

          本文标题:电源 | Battery系列(一) BatteryService

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