BatteryService学习笔记

来源:互联网 发布:surface laptop 知乎 编辑:程序博客网 时间:2024/06/07 05:30

BatteryService是提供接口用于获取电池信息,充电状态等;

BatteryService创建:

battery = new BatteryService(context, lights);ServiceManager.addService("battery", battery);

BatteryService构造方法:

1. BatteryService定义的3段阀值

a. mCriticalBatteryLevel表示严重低电,其值为4,。当电量低于该值时会强制关机;由config.xml中config_criticalBatteryWarningLevel控制

b. mLowBatteryWarningLevel表示低电,其值为15,。当电量低于该值时会报警,比如led等闪烁;由config.xml中config_lowBatteryWarningLevel控制

c. mLowBatteryCloseWarningLevel表示一旦电量大于此值,就脱离低电状态,即可停止警示灯,该值为20,;由config.xml中config_lowBatteryCloseWarningLevel控

 public BatteryService(Context context, LightsService lights) {        mContext = context;        mLed = new Led(context, lights);        mBatteryStats = BatteryStatsService.getService();/*获取3段阀值*/        mCriticalBatteryLevel = mContext.getResources().getInteger(                com.android.internal.R.integer.config_criticalBatteryWarningLevel);        mLowBatteryWarningLevel = mContext.getResources().getInteger(                com.android.internal.R.integer.config_lowBatteryWarningLevel);        mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(                com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);/*监视power_supply信息*/        mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply");        // watch for invalid charger messages if the invalid_charger switch exists        if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {            mInvalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger");        }        // set initial status        update();//查询HAL层,获取此时的电池信息}

2. update方法,用于查询HAL层电池信息

    private synchronized final void update() {        native_update();        processValues();    }

a. native_update: 更新Native层内部变量状态

//com_android_server_BatteryService.cpp/android_server_BatteryService_update

static void android_server_BatteryService_update(JNIEnv* env, jobject obj){//外接充电器    setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline);    //获取电池信息,通过JNI层设置到java层setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);    setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);        setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);    setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);    setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);        const int SIZE = 128;    char buf[SIZE];        if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0)        env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));    else        env->SetIntField(obj, gFieldIds.mBatteryStatus,                         gConstants.statusUnknown);        if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)        env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));    if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)        env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));}

电池信息表


b. processValues: 处理更新后的状态

private void processValues() {        boolean logOutlier = false;        long dischargeDuration = 0;        mBatteryLevelCritical = mBatteryLevel <= mCriticalBatteryLevel;        if (mAcOnline) {            mPlugType = BatteryManager.BATTERY_PLUGGED_AC;        } else if (mUsbOnline) {            mPlugType = BatteryManager.BATTERY_PLUGGED_USB;        } else {            mPlugType = BATTERY_PLUGGED_NONE;        }                // Let the battery stats keep track of the current level.        try {            mBatteryStats.setBatteryState(mBatteryStatus, mBatteryHealth,                    mPlugType, mBatteryLevel, mBatteryTemperature,                    mBatteryVoltage);        } catch (RemoteException e) {            // Should never happen.        }                shutdownIfNoPower();        shutdownIfOverTemp();        if (mBatteryStatus != mLastBatteryStatus ||                mBatteryHealth != mLastBatteryHealth ||                mBatteryPresent != mLastBatteryPresent ||                mBatteryLevel != mLastBatteryLevel ||                mPlugType != mLastPlugType ||                mBatteryVoltage != mLastBatteryVoltage ||                mBatteryTemperature != mLastBatteryTemperature ||                mInvalidCharger != mLastInvalidCharger) {            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 != mBatteryLevel) {                        dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;                        logOutlier = true;                        EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,                                mDischargeStartLevel, mBatteryLevel);                        // 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 = mBatteryLevel;                }            }            if (mBatteryStatus != mLastBatteryStatus ||                    mBatteryHealth != mLastBatteryHealth ||                    mBatteryPresent != mLastBatteryPresent ||                    mPlugType != mLastPlugType) {                EventLog.writeEvent(EventLogTags.BATTERY_STATUS,                        mBatteryStatus, mBatteryHealth, mBatteryPresent ? 1 : 0,                        mPlugType, mBatteryTechnology);            }            if (mBatteryLevel != mLastBatteryLevel ||                    mBatteryVoltage != mLastBatteryVoltage ||                    mBatteryTemperature != mLastBatteryTemperature) {                EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,                        mBatteryLevel, mBatteryVoltage, mBatteryTemperature);            }            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;            }            final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;            final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;            /* The ACTION_BATTERY_LOW broadcast is sent in these situations:             * - is just un-plugged (previously was plugged) and battery level is             *   less than or equal to WARNING, or             * - is not plugged and battery level falls to WARNING boundary             *   (becomes <= mLowBatteryWarningLevel).             */            final boolean sendBatteryLow = !plugged                    && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN                    && mBatteryLevel <= mLowBatteryWarningLevel                    && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);            sendIntent();            // Separate broadcast is sent for power connected / not connected            // since the standard intent will not wake any applications and some            // applications may want to have smart behavior based on this.            Intent statusIntent = new Intent();            statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);            if (mPlugType != 0 && mLastPlugType == 0) {                statusIntent.setAction(Intent.ACTION_POWER_CONNECTED);                mContext.sendBroadcast(statusIntent);            }            else if (mPlugType == 0 && mLastPlugType != 0) {                statusIntent.setAction(Intent.ACTION_POWER_DISCONNECTED);                mContext.sendBroadcast(statusIntent);            }            if (sendBatteryLow) {                mSentLowBatteryBroadcast = true;                statusIntent.setAction(Intent.ACTION_BATTERY_LOW);                mContext.sendBroadcast(statusIntent);            } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {                mSentLowBatteryBroadcast = false;                statusIntent.setAction(Intent.ACTION_BATTERY_OKAY);                mContext.sendBroadcast(statusIntent);            }            // Update the battery LED            mLed.updateLightsLocked();            // This needs to be done after sendIntent() so that we get the lastest battery stats.            if (logOutlier && dischargeDuration != 0) {                logOutlier(dischargeDuration);            }            mLastBatteryStatus = mBatteryStatus;            mLastBatteryHealth = mBatteryHealth;            mLastBatteryPresent = mBatteryPresent;            mLastBatteryLevel = mBatteryLevel;            mLastPlugType = mPlugType;            mLastBatteryVoltage = mBatteryVoltage;            mLastBatteryTemperature = mBatteryTemperature;            mLastBatteryLevelCritical = mBatteryLevelCritical;            mLastInvalidCharger = mInvalidCharger;        }    }

总结:

BatteryService主要是获取电池相关的内容,根据不同的情况作出相应的处理,比如低电关机,低电警告,提供获取电池信息接口给BatteryStatsService等。




0 0