Android8.0.0-r4——BatteryService

2024-03-06 08:30

本文主要是介绍Android8.0.0-r4——BatteryService,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

电池服务的启动过程

BatteryService是在systemServer启动核心服务的时候启动

1.在SystemServer中启动BatteryService服务

 代码路径:/frameworks/base/services/java/com/android/server/SystemServer.java

  (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/java/com/android/server/SystemServer.java)
259    public static void main(String[] args) {
260        new SystemServer().run();
261    }
 

在main中创建一个SystemServer的匿名对象并调用它的run函数

263    public SystemServer() {
264        // Check for factory test mode.
265        mFactoryTestMode = FactoryTest.getMode();
266        // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
267        mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
268    }

创建匿名对象,在构造函数中得到启动模式和sys.boot_completed的属性。用来判断是否为正常模式启动和boot启动是否完成。

在run函数中会对系统属性进行初始化设置,并启动一些关键的服务:

391        // Start services.
392        try {
393            traceBeginAndSlog("StartServices");
394            startBootstrapServices();
395            startCoreServices();//BatteryService在startCoreServices中创建的
396            startOtherServices();
397            SystemServerInitThreadPool.shutdown();

例如此次要说明的BatteryService服务就在startCoreServices()函数中

 
640    /**
641     * Starts some essential services that are not tangled up in the bootstrap process.
642     */
643    private void startCoreServices() {....................................
648
649        traceBeginAndSlog("StartBatteryService");
650        // Tracks the battery level.  Requires LightService.
651        mSystemServiceManager.startService(BatteryService.class);
652        traceEnd();
653..........................................
665    }
 

2. BatteryService的构造方法    

代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java        (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

159    public BatteryService(Context context) {
160        super(context);
161
162        mContext = context;
163        mHandler = new Handler(true /*async*/);
164        mLed = new Led(context, getLocalService(LightsManager.class));//内部类Led,控制不同电量下led灯的颜色
165        mBatteryStats = BatteryStatsService.getService(); //电量统计服务
166        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
167        //以下是根据配置文件,定义不同电量对应的等级
168        mCriticalBatteryLevel = mContext.getResources().getInteger(
169                com.android.internal.R.integer.config_criticalBatteryWarningLevel);//电池危急的电量;当电池电量低于此值时,将强制关机
170        mLowBatteryWarningLevel = mContext.getResources().getInteger(
171                com.android.internal.R.integer.config_lowBatteryWarningLevel);//低电警告的电量;当电池电量低于此值时,系统报警,例如闪烁LED灯等
172        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(
173                com.android.internal.R.integer.config_lowBatteryCloseWarningBump);//关闭低电警告的电量;当电池电量高于此值时,结束低电状态,停止警示灯
174        mShutdownBatteryTemperature = mContext.getResources().getInteger(
175                com.android.internal.R.integer.config_shutdownBatteryTemperature);//关闭电池的温度(温度失控,就会出现三星S7爆炸啥的......) 
176
177        // watch for invalid charger messages if the invalid_charger switch exists
178        if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {// 监控终端是否连接不匹配的充电器
179            UEventObserver invalidChargerObserver = new UEventObserver() {
180                @Override
181                public void onUEvent(UEvent event) {
182                    final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;
183                    synchronized (mLock) {
184                        if (mInvalidCharger != invalidCharger) {
185                            mInvalidCharger = invalidCharger;
186                        }
187                    }
188                }
189            };
190            invalidChargerObserver.startObserving(
191                    "DEVPATH=/devices/virtual/switch/invalid_charger");
192        }
193    }
194

整体来看BatteryService构造函数是比较简单的,主要的目的就是得到一些变量,从资源中获取一些预定的值。


2.3 BatteryService onStart方法

代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java        
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

onStart方法中 将BatteryService服务注册到ServiceManager,注册了底层电量变换的回调方法,最终调用BatteryService的update方法更新电池信息

195    @Override
196    public void onStart() {
197        IBinder b = ServiceManager.getService("batteryproperties");//获取电源属性服务的BinderProxy对象,电源属性服务运行在android的healthd进程中,对应文件为system/core/healthd/BatteryPropertiesRegistrar.cpp,此处java层通过Binder直接与native层通信
198        final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
199                IBatteryPropertiesRegistrar.Stub.asInterface(b);//向电源属性服务注册一个回调接口,当电源属性发生变化时,BatteryListener的batteryPropertiesChanged函数将被调用
200        try {
201            batteryPropertiesRegistrar.registerListener(new BatteryListener());//注册底层电量变化的监听,调用update更新电池信息。
202        } catch (RemoteException e) {
203            // Should never happen.
204        }
205
206        mBinderService = new BinderService();//注册BatteryService服务
207        publishBinderService("battery", mBinderService);//注册到service manager进程中
208        publishLocalService(BatteryManagerInternal.class, new LocalService());//对于基于LocalServices管理的对象而言,这个函数调用相当于单例模式的进阶版以后BatteryManagerInternal接口类型的对象,只能有BatteryService的内部类LocalService一个
209    }

BatteryService在onStart函数中主要完成一些服务注册、接口注册的工作


3.1 BatteryPropertiesRegistrar 

BatteryPropertiesRegistrar.h的定义:      

代码路径:/system/core/healthd/BatteryPropertiesRegistrar.h
(http://androidxref.com/8.0.0_r4/xref/system/core/healthd/BatteryPropertiesRegistrar.h)

17#ifndef HEALTHD_BATTERYPROPERTIES_REGISTRAR_H
18#define HEALTHD_BATTERYPROPERTIES_REGISTRAR_H
19..................................................
27
28namespace android {
29
30class BatteryPropertiesRegistrar : public BnBatteryPropertiesRegistrar,
31                                   public IBinder::DeathRecipient {
32public:
33    void publish(const sp<BatteryPropertiesRegistrar>& service);
34    void notifyListeners(const struct BatteryProperties& props);..........................................
46};
47
48};  // namespace android
49
50#endif // HEALTHD_BATTERYPROPERTIES_REGISTRAR_H


BatteryPropertiesRegistrar.cpp的实现

代码路径:/system/core/healthd/BatteryPropertiesRegistrar.cpp
(http://androidxref.com/8.0.0_r4/xref/system/core/healthd/BatteryPropertiesRegistrar.cpp)

30
31namespace android {
32
33void BatteryPropertiesRegistrar::publish(
34    const sp<BatteryPropertiesRegistrar>& service) {
35    defaultServiceManager()->addService(String16("batteryproperties"), service);//注册服务到service manager进程
36}
37
38void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) {
39    Vector<sp<IBatteryPropertiesListener> > listenersCopy;
40
41    // Binder currently may service an incoming oneway transaction whenever an
42    // outbound oneway call is made (if there is already a pending incoming
43    // oneway call waiting).  This is considered a bug and may change in the
44    // future.  For now, avoid recursive mutex lock while making outbound
45    // calls by making a local copy of the current list of listeners.
46    {
47        Mutex::Autolock _l(mRegistrationLock);
48        listenersCopy = mListeners;
49    }
50    for (size_t i = 0; i < listenersCopy.size(); i++) {
51        listenersCopy[i]->batteryPropertiesChanged(props);//通知观察者
52    }
53}
54
55void BatteryPropertiesRegistrar::registerListener(const sp<IBatteryPropertiesListener>& listener) {
56    {
57        if (listener == NULL)
58            return;
59        Mutex::Autolock _l(mRegistrationLock);
60        // check whether this is a duplicate
61        for (size_t i = 0; i < mListeners.size(); i++) {
62            if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) {
63                return;
64            }
65        }
66
67        mListeners.add(listener);//存储观察者
68        IInterface::asBinder(listener)->linkToDeath(this);
69    }
70    healthd_battery_update();//更新底层的电源状态,最终将调用到BatteryMonitor.cpp的update函数,也是BatteryService第一次启动,注册Listener后,立马就会更新一次电源信息
71}
72..............................................
117
118}  // namespace android
119
不展开native层healthd_battery_update的流程,主要是从大量的文件中读取电源的信息。此处,我们仅思考一下这种Java层和native层的Binder通信过程。

对等的Binder通信结构,即双方的主体均在native层,或都在Java层。 这次是客户端在Java层,服务端在native层。

其实仔细想想,这是完全符合Binder通信架构的。 
对于客户端而言,它只需要从service manager进程获取到服务端的BpBinder值,然后利用这个BpBinder值逐步构成Java层的BinderProxy对象(会进一步转化为基于业务的服务代理)。 

客户端根本就不要求服务端具有Java层的结构。在实际的通信过程中,客户端数据通过Binder驱动,传到服务端的native层。若native层就能够完成处理过程,就不需要往Java层作进一步的传输,直接返回结果即可。整个处理过程,对于客户端而言,完全是透明的。


3.2 回调接口的作用  

BatteryListener的回调接口:

代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java                              (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

936    private final class BatteryListener extends IBatteryPropertiesListener.Stub {
937        @Override public void batteryPropertiesChanged(BatteryProperties props) {
938            final long identity = Binder.clearCallingIdentity();
939            try {
940                BatteryService.this.update(props);//电源属性发生变化后,回调BatteryService的update函数
941            } finally {
942                Binder.restoreCallingIdentity(identity);
943            }
944       }
945    }


BatteryService的update函数定义:

代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java                              (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

321    private void update(BatteryProperties props) {
322        synchronized (mLock) {//mUpdatesStopped默认为false,通过shell command才有可能改变
323            if (!mUpdatesStopped) {
324                mBatteryProps = props;
325                // Process the new values.
326                processValuesLocked(false);//更新电源相关的信息
327            } else {
328                mLastBatteryProps.set(props);
329            }
330        }
331    }

BatteryService注册回调接口的作用是:更新其维护的电源信息


4. BatteryService onBootPhase方法

4.1 基础知识  

在SystemServiceManager中提供了以下接口:

代码路径:/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java                             (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java)

137    public void startBootPhase(final int phase) {
138        if (phase <= mCurrentPhase) {
139            throw new IllegalArgumentException("Next phase must be larger than previous");
140        }
141        mCurrentPhase = phase;
142
143        Slog.i(TAG, "Starting phase " + mCurrentPhase);
144        try {
145            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase);
146            final int serviceLen = mServices.size();
147            for (int i = 0; i < serviceLen; i++) {
148                final SystemService service = mServices.get(i);//SystemServer利用SystemServiceManager启动的系统服务,均会保留在mServices中
149                long time = System.currentTimeMillis();
150                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName());
151                try {
152                    service.onBootPhase(mCurrentPhase);//调用此时已经加入的service的onBootPhase函数
153                } catch (Exception ex) {
154                    throw new RuntimeException("Failed to boot service "
155                            + service.getClass().getName()
156                            + ": onBootPhase threw an exception during phase "
157                            + mCurrentPhase, ex);
158                }
159                warnIfTooLong(System.currentTimeMillis() - time, service, "onBootPhase");
160                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
161            }
162        } finally {
163            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
164        }
165    }


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

代码路径:/frameworks/base/services/core/java/com/android/server/SystemService.java                         (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/SystemService.java)

49public abstract class SystemService {
50    /*
51     * Boot Phases
52     */
53    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?
54
55    /**
56     * After receiving this boot phase, services can obtain lock settings data.
57     */
58    public static final int PHASE_LOCK_SETTINGS_READY = 480;
59
60    /**
61     * After receiving this boot phase, services can safely call into core system services
62     * such as the PowerManager or PackageManager.
63     */
64    public static final int PHASE_SYSTEM_SERVICES_READY = 500;
65
66    /**
67     * After receiving this boot phase, services can broadcast Intents.
68     */
69    public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
70
71    /**
72     * After receiving this boot phase, services can start/bind to third party apps.
73     * Apps will be able to make Binder calls into services at this point.
74     */
75    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
76
77    /**
78     * After receiving this boot phase, services can allow user interaction with the device.
79     * This phase occurs when boot has completed and the home application has started.
80     * System services may prefer to listen to this phase rather than registering a
81     * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
82     */
83    public static final int PHASE_BOOT_COMPLETED = 1000;
84
 

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

这么做的目的是: SystemServer会依次启动许多服务,但服务之间的功能是相互依赖的。 因此,每个服务刚被启动时,都完成最基本的初始化。当系统运行到某个阶段后,调用SystemServiceManager的startBootPhase函数, 于是所有的服务都可以进一步完成这个阶段可以进行的初始化工作。通过这种方式,每个服务的初始化过程可以按阶段分为好几个部分,增加了不同阶段的初始化工作的清晰度; 同时,每个阶段调用startBootPhase函数,就像一种同步机制一样,让所有服务的初始化进程保持一致的步调。

4.2 BatteryService的onBootPhase 

代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java                              (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

211    @Override
212    public void onBootPhase(int phase) {
213        if (phase == PHASE_ACTIVITY_MANAGER_READY) { //BatteryService只需要在PHASE_ACTIVITY_MANAGER_READY后,在进行部分的初始化即可
214            // check our power situation now that it is safe to display the shutdown dialog.
215            synchronized (mLock) {
216                ContentObserver obs = new ContentObserver(mHandler) {
217                    @Override
218                    public void onChange(boolean selfChange) {
219                        synchronized (mLock) {
220                            updateBatteryWarningLevelLocked();
221                        }
222                    }
223                };
224                final ContentResolver resolver = mContext.getContentResolver();
225                resolver.registerContentObserver(Settings.Global.getUriFor(
226                        Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
227                        false, obs, UserHandle.USER_ALL);//监听设置中低电量警告的电量值是否改变,改变时调用updateBatteryWarningLevelLocked函数
228                updateBatteryWarningLevelLocked();
229            }
230        }
231    }
232

BatteryService的onBootPhase函数主要是注册一个监听器,检测低电量警告的电量值是否改变,然后调用updateBatteryWarningLevelLocked函数


代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java                              (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

233    private void updateBatteryWarningLevelLocked() {
234        final ContentResolver resolver = mContext.getContentResolver();
235        int defWarnLevel = mContext.getResources().getInteger(
236                com.android.internal.R.integer.config_lowBatteryWarningLevel);//获取XML中配置的默认警告电量值
237        mLowBatteryWarningLevel = Settings.Global.getInt(resolver,
238                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel); //获取设置中用户定义的电量警告值
239        if (mLowBatteryWarningLevel == 0) {//用户没有定义,则使用默认的
240            mLowBatteryWarningLevel = defWarnLevel;
241        }
242        if (mLowBatteryWarningLevel < mCriticalBatteryLevel) {//警告值不能低于危险值
243            mLowBatteryWarningLevel = mCriticalBatteryLevel;
244        }
245        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(//计算出关闭警告的电量值
246                com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
247        processValuesLocked(true);//更新电池信息
248    }

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

代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java                              (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

333    private void processValuesLocked(boolean force) {//force表示是否强制更新信息,当force为false时,只有新旧信息不一致才更新
334        boolean logOutlier = false;
335        long dischargeDuration = 0;
336
337        mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);//判断当前电量是否危险;mBatteryProps由电源属性服务提供
338        if (mBatteryProps.chargerAcOnline) {//得到充电的类型
339            mPlugType = BatteryManager.BATTERY_PLUGGED_AC;//充电状态
340        } else if (mBatteryProps.chargerUsbOnline) {
341            mPlugType = BatteryManager.BATTERY_PLUGGED_USB;//Usb链接状态
342        } else if (mBatteryProps.chargerWirelessOnline) {
343            mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;//无线充电状态
344        } else {
345            mPlugType = BATTERY_PLUGGED_NONE;//未充电状态
346        }
347
348        if (DEBUG) {
349            Slog.d(TAG, "Processing new values: "
350                    + "chargerAcOnline=" + mBatteryProps.chargerAcOnline
351                    + ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
352                    + ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
353                    + ", maxChargingCurrent" + mBatteryProps.maxChargingCurrent
354                    + ", maxChargingVoltage" + mBatteryProps.maxChargingVoltage
355                    + ", batteryStatus=" + mBatteryProps.batteryStatus
356                    + ", batteryHealth=" + mBatteryProps.batteryHealth
357                    + ", batteryPresent=" + mBatteryProps.batteryPresent
358                    + ", batteryLevel=" + mBatteryProps.batteryLevel
359                    + ", batteryTechnology=" + mBatteryProps.batteryTechnology
360                    + ", batteryVoltage=" + mBatteryProps.batteryVoltage
361                    + ", batteryChargeCounter=" + mBatteryProps.batteryChargeCounter
362                    + ", batteryFullCharge=" + mBatteryProps.batteryFullCharge
363                    + ", batteryTemperature=" + mBatteryProps.batteryTemperature
364                    + ", mBatteryLevelCritical=" + mBatteryLevelCritical
365                    + ", mPlugType=" + mPlugType);
366        }
367
368        // Let the battery stats keep track of the current level.
369        try {//将信息递交给电源统计服务
370            mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
371                    mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
372                    mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter,
373                    mBatteryProps.batteryFullCharge);
374        } catch (RemoteException e) {
375            // Should never happen.
376        }
377
378        shutdownIfNoPowerLocked();//电池电量低(batteryLevel==0)且未充电时,拉起关机对话框
379        shutdownIfOverTempLocked();//电池温度过高(默认为68C),拉起关机对话框
380        //强制更新,或电源相关属性发生变化时,进行对应操作
381        if (force || (mBatteryProps.batteryStatus != mLastBatteryStatus ||
382                mBatteryProps.batteryHealth != mLastBatteryHealth ||
383                mBatteryProps.batteryPresent != mLastBatteryPresent ||
384                mBatteryProps.batteryLevel != mLastBatteryLevel ||
385                mPlugType != mLastPlugType ||
386                mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
387                mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
388                mBatteryProps.maxChargingCurrent != mLastMaxChargingCurrent ||
389                mBatteryProps.maxChargingVoltage != mLastMaxChargingVoltage ||
390                mBatteryProps.batteryChargeCounter != mLastChargeCounter ||
391                mInvalidCharger != mLastInvalidCharger)) {
392
393            if (mPlugType != mLastPlugType) {//充电状态发生变化(不关注充电的方式,即usb变为AC之类的,只是关注充电变为未充电等事件)
394                if (mLastPlugType == BATTERY_PLUGGED_NONE) {
395                    // discharging -> charging
396
397                    // There's no value in this data unless we've discharged at least once and the
398                    // battery level has changed; so don't log until it does.
399                    if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {//记录一下不充电待机的情况下,耗电量及耗电时长
400                        dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
401                        logOutlier = true;
402                        EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
403                                mDischargeStartLevel, mBatteryProps.batteryLevel);
404                        // make sure we see a discharge event before logging again
405                        mDischargeStartTime = 0;
406                    }
407                } else if (mPlugType == BATTERY_PLUGGED_NONE) {//本次充电结束,重新开始计算耗电情况,于是初始化下面的变量
408                    // charging -> discharging or we just powered up
409                    mDischargeStartTime = SystemClock.elapsedRealtime();
410                    mDischargeStartLevel = mBatteryProps.batteryLevel;
411                }
412            }//记录电源的状态信息、电量信息
413            if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
414                    mBatteryProps.batteryHealth != mLastBatteryHealth ||
415                    mBatteryProps.batteryPresent != mLastBatteryPresent ||
416                    mPlugType != mLastPlugType) {
417                EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
418                        mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0,
419                        mPlugType, mBatteryProps.batteryTechnology);
420            }
421            if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
422                // Don't do this just from voltage or temperature changes, that is
423                // too noisy.
424                EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
425                        mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
426            }//电池电量低到危险的程度,且没充电,记录耗电时间
427            if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
428                    mPlugType == BATTERY_PLUGGED_NONE) {
429                // We want to make sure we log discharge cycle outliers
430                // if the battery is about to die.
431                dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
432                logOutlier = true;
433            }
434            //判断电源是否处于低电模式
435            if (!mBatteryLevelLow) {
436                // Should we now switch in to low battery mode?
437                if (mPlugType == BATTERY_PLUGGED_NONE 
438                        && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel) {
439                    mBatteryLevelLow = true;// 当前未充电,且当前电量小于提醒电量,设置低电量为true
440                }
441            } else {
442                // Should we now switch out of low battery mode?
443                if (mPlugType != BATTERY_PLUGGED_NONE) {
444                    mBatteryLevelLow = false;//开始充电,退出低电量模式
445                } else if (mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel)  {
446                    mBatteryLevelLow = false;//电池电量充足,退出低电量模式
447                } else if (force && mBatteryProps.batteryLevel >= mLowBatteryWarningLevel) {
448                    // If being forced, the previous state doesn't matter, we will just
449                    // absolutely check to see if we are now above the warning level.
450                    mBatteryLevelLow = false;//强制刷新时,忽略之前的状态
451                }
452            }
453
454            mSequence++;
455
456            // Separate broadcast is sent for power connected / not connected
457            // since the standard intent will not wake any applications and some
458            // applications may want to have smart behavior based on this.
459            if (mPlugType != 0 && mLastPlugType == 0) {
460                final Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
461                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
462                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
463                mHandler.post(new Runnable() {
464                    @Override
465                    public void run() {
466                        mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
467                    }
468                });
469            }
470            else if (mPlugType == 0 && mLastPlugType != 0) {
471                final Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
472                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
473                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
474                mHandler.post(new Runnable() {
475                    @Override
476                    public void run() {
477                        mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
478                    }
479                });
480            }
481
482            if (shouldSendBatteryLowLocked()) {
483                mSentLowBatteryBroadcast = true;
484                final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
485                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
486                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
487                mHandler.post(new Runnable() {
488                    @Override
489                    public void run() {
490                        mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
491                    }
492                });
493            } else if (mSentLowBatteryBroadcast &&
494                    mBatteryProps.batteryLevel >= mLowBatteryCloseWarningLevel) {
495                mSentLowBatteryBroadcast = false;
496                final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
497                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
498                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);
499                mHandler.post(new Runnable() {
500                    @Override
501                    public void run() {
502                        mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
503                    }
504                });
505            }
506
507            // We are doing this after sending the above broadcasts, so anything processing
508            // them will get the new sequence number at that point.  (See for example how testing
509            // of JobScheduler's BatteryController works.)
510            sendIntentLocked();//发送广播ACTION_BATTERY_CHANGED,内含电源当前的全部信息
511
512            // Update the battery LED
513            mLed.updateLightsLocked();//根据电源的电量和状态,改变LED灯的颜色
514
515            // This needs to be done after sendIntent() so that we get the lastest battery stats.
516            if (logOutlier && dischargeDuration != 0) {
517                logOutlierLocked(dischargeDuration);//利用BatteryInfoService记录耗电情况的dump文件
518            }
519           //更新本地变量
520            mLastBatteryStatus = mBatteryProps.batteryStatus;
521            mLastBatteryHealth = mBatteryProps.batteryHealth;
522            mLastBatteryPresent = mBatteryProps.batteryPresent;
523            mLastBatteryLevel = mBatteryProps.batteryLevel;
524            mLastPlugType = mPlugType;
525            mLastBatteryVoltage = mBatteryProps.batteryVoltage;
526            mLastBatteryTemperature = mBatteryProps.batteryTemperature;
527            mLastMaxChargingCurrent = mBatteryProps.maxChargingCurrent;
528            mLastMaxChargingVoltage = mBatteryProps.maxChargingVoltage;
529            mLastChargeCounter = mBatteryProps.batteryChargeCounter;
530            mLastBatteryLevelCritical = mBatteryLevelCritical;
531            mLastInvalidCharger = mInvalidCharger;
532        }
533    }


代码路径:/frameworks/base/services/core/java/com/android/server/BatteryService.java                              (http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java)

mLed.updateLightsLocked

881    private final class Led {
882        private final Light mBatteryLight;
883
884        private final int mBatteryLowARGB;
885        private final int mBatteryMediumARGB;
886        private final int mBatteryFullARGB;
887        private final int mBatteryLedOn;
888        private final int mBatteryLedOff;
889
890        public Led(Context context, LightsManager lights) {
891            mBatteryLight = lights.getLight(LightsManager.LIGHT_ID_BATTERY);
892
893            mBatteryLowARGB = context.getResources().getInteger(
894                    com.android.internal.R.integer.config_notificationsBatteryLowARGB);
895            mBatteryMediumARGB = context.getResources().getInteger(
896                    com.android.internal.R.integer.config_notificationsBatteryMediumARGB);
897            mBatteryFullARGB = context.getResources().getInteger(
898                    com.android.internal.R.integer.config_notificationsBatteryFullARGB);
899            mBatteryLedOn = context.getResources().getInteger(
900                    com.android.internal.R.integer.config_notificationsBatteryLedOn);
901            mBatteryLedOff = context.getResources().getInteger(
902                    com.android.internal.R.integer.config_notificationsBatteryLedOff);
903        }
904
905        /**
906         * Synchronize on BatteryService.
907         */
908        public void updateLightsLocked() {
909            final int level = mBatteryProps.batteryLevel;
910            final int status = mBatteryProps.batteryStatus;
911            if (level < mLowBatteryWarningLevel) {//电量低于BatteryWarning的电量
912                if (status == BatteryManager.BATTERY_STATUS_CHARGING) {//已经连接上充电
913                    // Solid red when battery is charging
914                    mBatteryLight.setColor(mBatteryLowARGB);//指示灯显示红色
915                } else {
916                    // Flash red when battery is low and not charging
917                    mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED,
918                            mBatteryLedOn, mBatteryLedOff);//没有连接充电线,红灯闪烁
919                }
920            } else if (status == BatteryManager.BATTERY_STATUS_CHARGING
921                    || status == BatteryManager.BATTERY_STATUS_FULL) {//当前正在充电或者当前电量已经充满
922                if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) {
923                    // Solid green when full or charging and nearly full
924                    mBatteryLight.setColor(mBatteryFullARGB);//当电池已经充满或者快要充满的时候指示灯显示绿色
925                } else {
926                    // Solid orange when charging and halfway full
927                    mBatteryLight.setColor(mBatteryMediumARGB);//当正在充电或者电量超过一半的时候,指示灯显示橘黄色
928                }
929            } else {
930                // No lights if not charging and not low
931                mBatteryLight.turnOff();//其他正常情况指示灯关闭 
932            }
933        }
934    }

更新LED等方法主要根据电池电量和充电状态来决定LED指示灯的颜色和显示方式。低于警告电量的时候LED指示灯显示红色,当电池充满电的时候指示灯显示绿色




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

这篇关于Android8.0.0-r4——BatteryService的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/779423

相关文章

Android7.0+ 、Android8.0+Android9.0+、Android10.0+安装指定apk、下载后的apk方法

前言:你的apk文件即使有文件读取权限,若想安装下载后的app,我们需要将apk文件暴露给系统安装进程 apk安装所需权限 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.WRITE_EXTER

android8.0 桌面图标适配

开始自己的android开发记录历程。 上周开发应用完结,结果老板装上后,应用logo居然显示android机器人(老板华为mete9 pro的机器)。 查找后是android8.0图标适配原因。 在sutdio3.0后,创建的targetSdkversion大于等于27的话,在res文件夹下将会自动创建一个mipmap-anydpi-v26的文件夹 android8.0后的桌面图标将只会

android8.0应用崩溃,报错: Only fullscreen opaque activities can request orientation

错误日志: Caused by: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation 字面意思就是说:只有不透明的全屏activity可以自主设置界面方向。 网上搜了搜,发现不是个例,这个问题出现在android8.0以上。原因是我们给Activity同时设置

Android8.0使用ninja模块编译Settings(五十四)

Android8.0使用ninja模块编译Settings  查看out目录# lunch aosp_arm64-eng//查看选项# ln -s out/combined-aosp_arm64.ninja build.ninja# ninja Settingsmake编译完一个项目后,如果再执行make,会花费较长时间重新编译部分内容,而使用Ninja以后,增量编译做得比较完善。

【Android 10 源码】healthd 模块 BatteryService 初始化

BatteryService 是在 SystemServer 中启动的,BatteryService 监控设备电池的充电状态和充电水平。当这些值改变时,这个服务会将这些新值广播给所有正在监听 ACTION_BATTERY_CHANGED 的广播接收者。 BatteryService 被划分到核心服务类别。 frameworks/base/services/java/com/android/se

IBM x230笔记本 电路图 逻辑图 运行逻辑图 X230 11232-1_final_r4.pdf 电路板图

以前给朋友修本时找到的,在这里备份一下,也提供给有需要的朋友一用。 城通网盘下载地址 线路图pdf X230 11232-1_final_r4.pdf: https://545c.com/file/20096151-422817783 线板图bdv 11232-1.bdv: https://545c.com/file/20096151-422818176

【解决方案】荣耀系统Android8.0 system目录Read-only file system

本来以为直接把Charles证书改成系统证书格式,然后通过mt管理器root之后移动到系统证书目录就行了,结果访问baidu仍然显示网络错误,折腾一晚上。安装为用户证书,又与系统证书冲突。 手机型号:荣耀v10 EMUI:8.0.0 Android:8.0.0 简单说一下坑点 1、直接移动到系统证书目录默认权限660,可读写不可执行,访问百度证书过期 2、荣耀系统root为阉割版,

创建应用快捷方式,教你如何适配android7.1以上和android8.0的新api ShortcutManager

最近公司有个需求,如何让用户快速使用App里面的某一个小功能,很显然创建桌面快捷很符合这个需求。效果页面可以参考微信或者支付宝的小程序添加到桌面快捷。 由于android7.1以上出了新的创建快捷方式,使用新的api ShortcutManager管理一个应用程序的快捷方式,ShortcutManager支持两种创建快捷方式,分别为:静态快捷方式和动态快捷方式。只要长按APP图标就会弹出快捷方式

CiteSpace下载及常见问题“6.2.R2(64-bit) Basic版无法验证,目前最新版为6.2.R4”“通常不会下载.exe,请在打开前确保信任.exe”

核心步骤:下载CiteSpace最新版6.2.4(截至23年7月26日)及解决遇到问题(本文不含Java语言配备步骤) 文章后附6.2.4安装包,仅供参考 1.CiteSpace下载 (1)官网下载,不要花钱 下载 (drexel.edu)http://cluster.ischool.drexel.edu/~cchen/citespace/download/ (2)点击绿色按钮“Down

android8.0编译记录

Android8.0的正式版在8月21日正式发布,我打算亲自动手编一个可以跑在nexus 6p上的rom测试一下,下面是编译过程中的一些记录一、下载前准备1,我使用自己的mac进行编译,限于存储容量,另外准备了一个移动硬盘。首先要将移动硬盘格式化为区分大小写的,可以使用ma自带的磁盘工具来完成。2,安装好jdk,最好使用最新的jdk版本来编译Android8.0,一开始没有使用最新的jdk,编