基于Android 11 BatteryService 分析

基于Android 11 BatteryService 分析,第1张

概述基于Android11BatteryService分析BatteryService介绍 BatteryService是电池管理的重要服务,该服务继承SystemService,主要用于管理电池的充电状态,充电百分比等。初始化数据mHandler=newHandler(true/*async*/);//Led封装了LightsManager,不同电量

基于AndroID 11 BatteryService 分析

BatteryService 介绍 

BatteryService是电池管理的重要服务,该服务继承SystemService,主要用于管理 电池的充电状态,充电百分比等。

初始化数据

        mHandler = new Handler(true /*async*/);        //Led封装了lightsManager,不同电量下led灯的颜色就由它来控制        mLed = new Led(context, getLocalService(lightsManager.class));        mBatteryStats = BatteryStatsService.getService();        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);        //读取临界值电量配置        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);220        // watch for invalID charger messages if the invalID_charger switch exists221        if (new file("/sys/devices/virtual/switch/invalID_charger/state").exists()) {222            UEventObserver invalIDChargerObserver = new UEventObserver() {223                @OverrIDe224                public voID onUEvent(UEvent event) {225                    final int invalIDCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;226                    synchronized (mlock) {227                        if (mInvalIDCharger != invalIDCharger) {228                            mInvalIDCharger = invalIDCharger;229                        }230                    }231                }232            };233            invalIDChargerObserver.startObserving(234                    "DEVPATH=/devices/virtual/switch/invalID_charger");

 

238    @OverrIDe239    public voID onStart() {240        registerHealthCallback();//注册接口241242        mBinderService = new BinderService();//将自己注册到service manager进程中243        publishBinderService("battery", mBinderService);244        mBatteryPropertIEsRegistrar = new BatteryPropertIEsRegistrar();//将自己注册到service manager进程中245        publishBinderService("batterypropertIEs", mBatteryPropertIEsRegistrar);/以后BatteryManagerInternal接口类型的对象,只能有BatteryService的内部类LocalService一个246        publishLocalService(BatteryManagerInternal.class, new LocalService());247    }

 注册了底层电量变换的回调方法,最终调用BatteryService的update方法更新电池信息

271    private voID registerHealthCallback() {272        traceBegin("HealthInitWrapper");273        mHealthServiceWrapper = new HealthServiceWrapper();274        mHealthHalCallback = new HealthHalCallback();275        // IHealth is lazily retrIEved.276        try {277            mHealthServiceWrapper.init(mHealthHalCallback,278                    new HealthServiceWrapper.IServiceManagersupplier() {},279                    new HealthServiceWrapper.IHealthsupplier() {});280        } catch (remoteexception ex) {281            Slog.e(TAG, "health: cannot register callback. (remoteexception)");282            throw ex.rethrowFromSystemServer();283        } catch (NoSuchElementException ex) {284            Slog.e(TAG, "health: cannot register callback. (no supported health HAL service)");285            throw ex;286        } finally {287            traceEnd();288        }289290        traceBegin("HealthInitWaitUpdate");291        // init register for new service notifications, and IServiceManager should return the292        // existing service in a near future. Wait for this.update() to instantiate293        // the initial mHealthInfo.294        long beforeWait = SystemClock.uptimeMillis();295        synchronized (mlock) {296            while (mHealthInfo == null) {297                Slog.i(TAG, "health: Waited " + (SystemClock.uptimeMillis() - beforeWait) +298                        "ms for callbacks. Waiting another " + HEALTH_HAL_WAIT_MS + " ms...");299                try {300                    mlock.wait(HEALTH_HAL_WAIT_MS);301                } catch (InterruptedException ex) {302                    Slog.i(TAG, "health: InterruptedException when waiting for update. "303                        + " Continuing...");304                }305            }306        }307308        Slog.i(TAG, "health: Waited " + (SystemClock.uptimeMillis() - beforeWait)309                + "ms and received the update.");310        traceEnd();311    }
onBootPhase
onBootPhase()函数主要是注册一个监听器,检测低电量警告的电量值是否改变,然后调用updateBatteryWarningLevelLocked()函数。250    public voID onBootPhase(int phase) {251        if (phase == PHASE_ACTIVITY_MANAGER_READY) {252            // check our power situation Now that it is safe to display the shutdown dialog.253            synchronized (mlock) {254                ContentObserver obs = new ContentObserver(mHandler) {255                    @OverrIDe256                    public voID onChange(boolean selfChange) {257                        synchronized (mlock) {258                            updateBatteryWarningLevelLocked();259                        }260                    }261                };//监听设置中低电量警告的电量值是否改变,改变时调用updateBatteryWarningLevelLocked函数262                final ContentResolver resolver = mContext.getContentResolver();263                resolver.registerContentObserver(Settings.Global.getUriFor(264                        Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),265                        false, obs, UserHandle.USER_ALL);266                updateBatteryWarningLevelLocked();267            }268        }313    private voID updateBatteryWarningLevelLocked() {314        final ContentResolver resolver = mContext.getContentResolver();//获取默认的警告电量值315        int defWarnLevel = mContext.getResources().getInteger(316                com.androID.internal.R.integer.config_lowBatteryWarningLevel);//获取默认的警告电量值317        mLowBatteryWarningLevel = Settings.Global.getInt(resolver,318                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);319        if (mLowBatteryWarningLevel == 0) {320            mLowBatteryWarningLevel = defWarnLevel;321        }322        if (mLowBatteryWarningLevel < mCriticalbatterylevel) {323            mLowBatteryWarningLevel = mCriticalbatterylevel;324        }//计算出关闭警告的电量值325        mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(326                com.androID.internal.R.integer.config_lowBatteryCloseWarningBump);//调用该方法来真正的更新电池信息327        processValuesLocked(true);328    }在该方法中主要来计算获取警告的电量值和关闭警告的电量值,然后调用processValuesLocked()方法来做真正的更新。我们知道当监听的底层电池电量发生变化的时候,回调update()方法,最终也会调用该方法来更新,那就来分析下该方法的具体实现。466    private voID processValuesLocked(boolean force) {467        boolean logoutlIEr = false;468        long dischargeDuration = 0;469470        mbatterylevelCritical =471            mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNowN472            && mHealthInfo.batterylevel <= mCriticalbatterylevel;473        if (mHealthInfo.chargerAcOnline) {474            mPlugType = BatteryManager.BATTERY_PLUGGED_AC; //充电状态475        } else if (mHealthInfo.chargerUsbOnline) {476            mPlugType = BatteryManager.BATTERY_PLUGGED_USB; usb连击477        } else if (mHealthInfo.chargerWirelessOnline) {478            mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; 无线充电479        } else {480            mPlugType = BATTERY_PLUGGED_NONE;481        }// 判断当前是否是危险电量状态 根据底层提供的电池数据,判断当前手机的充电状态490        // Let the battery stats keep track of the current level.491        try {//电池属性改变的时候,会将全部信息写到mBatteryStats中,app端从mBatteryStats中获取当前电池的电量以及状态492            mBatteryStats.setBatteryState(mHealthInfo.batteryStatus, mHealthInfo.batteryHealth,493                    mPlugType, mHealthInfo.batterylevel, mHealthInfo.batteryTemperature,494                    mHealthInfo.batteryVoltage, mHealthInfo.batteryChargeCounter,495                    mHealthInfo.batteryFullCharge,496                    mHealthInfo2p1.batteryChargeTimetoFullNowSeconds);497        } catch (remoteexception e) {498            // Should never happen.499        }500        //电池电量低(batterylevel==0)且未充电时,d出关机对话501        shutdownIfnopowerLocked();            //电池温度过高(默认为68C),d出关机对话框502        shutdownIfOverTempLocked();//强制更新,或电源相关属性发生变化时,进行对应 *** 作504        if (force || (mHealthInfo.batteryStatus != mLastBatteryStatus ||505                mHealthInfo.batteryHealth != mLastBatteryHealth ||506                mHealthInfo.batteryPresent != mLastBatteryPresent ||507                mHealthInfo.batterylevel != mLastbatterylevel ||508                mPlugType != mLastPlugType ||509                mHealthInfo.batteryVoltage != mLastBatteryVoltage ||510                mHealthInfo.batteryTemperature != mLastBatteryTemperature ||511                mHealthInfo.maxChargingCurrent != mLastMaxChargingCurrent ||512                mHealthInfo.maxChargingVoltage != mLastMaxChargingVoltage ||513                mHealthInfo.batteryChargeCounter != mLastChargeCounter ||514                mInvalIDCharger != mLastInvalIDCharger)) {515516            if (mPlugType != mLastPlugType) {//上次是不充电状态,现在开始充电了,即由不充电变为充电状态517                if (mLastPlugType == BATTERY_PLUGGED_NONE) {518                    // discharging -> charging state change519                    mChargeStartLevel = mHealthInfo.batterylevel;520                    mChargeStartTime = SystemClock.elapsedRealtime();521522                    final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);523                    builder.setType(MetricsEvent.TYPE_ACTION);524                    builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mPlugType);525                    builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,526                            mHealthInfo.batterylevel);527                    mMetricslogger.write(builder);528529                    // There's no value in this data unless we've discharged at least once and the530                    // battery level has changed; so don't log until it does.531                    if (mdischargeStartTime != 0 && mdischargeStartLevel != mHealthInfo.batterylevel) {532                        dischargeDuration = SystemClock.elapsedRealtime() - mdischargeStartTime;533                        logoutlIEr = true;534                        EventLog.writeEvent(EventLogTags.BATTERY_disCHARGE, dischargeDuration,535                                mdischargeStartLevel, mHealthInfo.batterylevel);536                        // make sure we see a discharge event before logging again537                        mdischargeStartTime = 0;538                    }539                } else if (mPlugType == BATTERY_PLUGGED_NONE) { //即由充电变为不充电状态540                    // charging -> discharging or we just powered up                        //本次充电结束,重新开始计算耗电情况,于是初始化下面的变量541                    mdischargeStartTime = SystemClock.elapsedRealtime();542                    mdischargeStartLevel = mHealthInfo.batterylevel;543544                    long chargeDuration = SystemClock.elapsedRealtime() - mChargeStartTime;545                    if (mChargeStartTime != 0 && chargeDuration != 0) {546                        final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);547                        builder.setType(MetricsEvent.TYPE_disMISS);548                        builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mLastPlugType);549                        builder.addTaggedData(MetricsEvent.FIELD_CHARGING_DURATION_MILliS,550                                chargeDuration);551                        builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,552                                mChargeStartLevel);553                        builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_END,554                                mHealthInfo.batterylevel);555                        mMetricslogger.write(builder);556                    }557                    mChargeStartTime = 0;558                }559            }                //以下是记录电源的状态信息和电量信息560            if (mHealthInfo.batteryStatus != mLastBatteryStatus ||561                    mHealthInfo.batteryHealth != mLastBatteryHealth ||562                    mHealthInfo.batteryPresent != mLastBatteryPresent ||563                    mPlugType != mLastPlugType) {564                EventLog.writeEvent(EventLogTags.BATTERY_STATUS,565                        mHealthInfo.batteryStatus, mHealthInfo.batteryHealth, mHealthInfo.batteryPresent ? 1 : 0,566                        mPlugType, mHealthInfo.batteryTechnology);567            }568            if (mHealthInfo.batterylevel != mLastbatterylevel) {569                // Don't do this just from voltage or temperature changes, that is570                // too noisy.571                EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,572                        mHealthInfo.batterylevel, mHealthInfo.batteryVoltage, mHealthInfo.batteryTemperature);573            }                电池电量低到危险的程度,且没充电,记录耗电时间574            if (mbatterylevelCritical && !mLastbatterylevelCritical &&575                    mPlugType == BATTERY_PLUGGED_NONE) {576                // We want to make sure we log discharge cycle outlIErs577                // if the battery is about to dIE.578                dischargeDuration = SystemClock.elapsedRealtime() - mdischargeStartTime;579                logoutlIEr = true;580            }581            //以下是判断电源是否处于低电模式582            if (!mbatterylevelLow) {583                // Should we Now switch in to low battery mode?584                if (mPlugType == BATTERY_PLUGGED_NONE585                        && mHealthInfo.batteryStatus !=586                           BatteryManager.BATTERY_STATUS_UNKNowN587                        && mHealthInfo.batterylevel <= mLowBatteryWarningLevel) {588                    mbatterylevelLow = true;589                }590            } else {591                // Should we Now switch out of low battery mode?592                if (mPlugType != BATTERY_PLUGGED_NONE) {593                    mbatterylevelLow = false;594                } else if (mHealthInfo.batterylevel >= mLowBatteryCloseWarningLevel)  {595                    mbatterylevelLow = false;596                } else if (force && mHealthInfo.batterylevel >= mLowBatteryWarningLevel) {597                    // If being forced, the prevIoUs state doesn't matter, we will just598                    // absolutely check to see if we are Now above the warning level.599                    mbatterylevelLow = false;600                }601            }602603            mSequence++;604605            // Separate broadcast is sent for power connected / not connected606            // since the standard intent will not wake any applications and some607            // applications may want to have smart behavior based on this.                //以下是单独发送一些广播信息,通知外界电池属性的变化:                //通知进入充电状态,或离开充电状态                //通知电源进入低电模式,或离开低电模式608            if (mPlugType != 0 && mLastPlugType == 0) {609                final Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);610                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);611                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);612                mHandler.post(new Runnable() {613                    @OverrIDe614                    public voID run() {615                        mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);616                    }617                });618            }619            else if (mPlugType == 0 && mLastPlugType != 0) {620                final Intent statusIntent = new Intent(Intent.ACTION_POWER_disCONNECTED);621                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);622                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);623                mHandler.post(new Runnable() {624                    @OverrIDe625                    public voID run() {626                        mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);627                    }628                });629            }630631            if (shouldSendBatteryLowLocked()) {632                mSentLowBatterybroadcast = true;633                final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);634                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);635                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);636                mHandler.post(new Runnable() {637                    @OverrIDe638                    public voID run() {639                        mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);640                    }641                });642            } else if (mSentLowBatterybroadcast &&643                    mHealthInfo.batterylevel >= mLowBatteryCloseWarningLevel) {644                mSentLowBatterybroadcast = false;645                final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);646                statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);647                statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);648                mHandler.post(new Runnable() {649                    @OverrIDe650                    public voID run() {651                        mContext.sendbroadcastAsUser(statusIntent, UserHandle.ALL);652                    }653                });654            }655656            // We are doing this after sending the above broadcasts, so anything processing657            // them will get the new sequence number at that point.  (See for example how testing658            // of JobScheduler's BatteryController works.)659            sendBatteryChangedIntentLocked();//通知改变660            if (mLastbatterylevel != mHealthInfo.batterylevel || mLastPlugType != mPlugType) {661                sendbatterylevelChangedIntentLocked();662            }663664665            // Update the battery LED666            mLed.updatelightsLocked();667668            // This needs to be done after sendIntent() so that we get the lastest battery stats.669            if (logoutlIEr && dischargeDuration != 0) {670                logoutlIErLocked(dischargeDuration);671            }672673            mLastBatteryStatus = mHealthInfo.batteryStatus;674            mLastBatteryHealth = mHealthInfo.batteryHealth;675            mLastBatteryPresent = mHealthInfo.batteryPresent;676            mLastbatterylevel = mHealthInfo.batterylevel;677            mLastPlugType = mPlugType;678            mLastBatteryVoltage = mHealthInfo.batteryVoltage;679            mLastBatteryTemperature = mHealthInfo.batteryTemperature;680            mLastMaxChargingCurrent = mHealthInfo.maxChargingCurrent;681            mLastMaxChargingVoltage = mHealthInfo.maxChargingVoltage;682            mLastChargeCounter = mHealthInfo.batteryChargeCounter;683            mLastbatterylevelCritical = mbatterylevelCritical;684            mLastInvalIDCharger = mInvalIDCharger;685        }686    }

 

 

总结

以上是内存溢出为你收集整理的基于Android 11 BatteryService 分析全部内容,希望文章能够帮你解决基于Android 11 BatteryService 分析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1041542.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-24
下一篇2022-05-24

发表评论

登录后才能评论

评论列表(0条)

    保存