Android快充流程

本文是基于android11源码分析,带你一起了解android快速充电的基本流程。

Android原生在充电时下拉状态栏上会有以下之一的提示

"正在充电(还需xxx充满)"

"正在快速充电(还需xxx充满)"

"正在慢速充电(还需xxx充满)"

下面我们以快速充电作为切入点,进行分析。

这个提示是属于SystemUI的,我们直接在SystemUI下搜索"正在快速充电",发现这个字符串的ID是keyguard_indication_charging_time_fast,并且在

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\KeyguardIndicationController.java被使用的。

KeyguardIndicationController.java
protected String computePowerIndication() {
    ........
    if (mPowerPluggedInWired) {
        switch (mChargingSpeed) {
            case BatteryStatus.CHARGING_FAST:
                chargingId = hasChargingTime
                        ? R.string.keyguard_indication_charging_time_fast//正在快速充电(还需xxx充满)的字符串ID
                        : R.string.keyguard_plugged_in_charging_fast;
.............
}

mChargingSpeed是区分快速充电/正常充电/慢速充电,它的值是在BaseKeyguardCallback回调的传回来的

protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
    public static final int HIDE_DELAY_MS = 5000;

    @Override
    public void onRefreshBatteryInfo(BatteryStatus status) {
        ...............
        mChargingSpeed = status.getChargingSpeed(mContext);//配置充电速度
        mBatteryLevel = status.level;
       ..............
    }
BatteryStatus.java
public final int getChargingSpeed(Context context) {
    final int slowThreshold = context.getResources().getInteger(
            R.integer.config_chargingSlowlyThreshold);//慢速充电
    final int fastThreshold = context.getResources().getInteger(
            R.integer.config_chargingFastThreshold);//快速充电
    return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
            maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
                    maxChargingWattage > fastThreshold ? CHARGING_FAST :
                            CHARGING_REGULAR;
}

config_chargingFastThreshold这个值的配置是在SettingLib包下

frameworks/base/packages/SettingsLib/res/values/config.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- Threshold in micro watts below which a charger is rated as "slow"; 1A @ 5V -->
    <integer name="config_chargingSlowlyThreshold">5000000</integer>

    <!-- Threshold in micro watts above which a charger is rated as "fast"; 1.5A @ 5V  -->
    <integer name="config_chargingFastThreshold">7500000</integer>
</resources>

到这里可以看到,显示充电快慢是可以通过config配置的,默认情况下充电功率小于5W显示慢速充电,充电瓦数大于7.5W显示快速充电,在5W和7.5W之间显示正常充电

接着看maxChargingWattage 是由BatteryStatus构造函数传入计算得到的,先看BatteryStatus的构造函数从哪里调用的。

protected KeyguardUpdateMonitorCallback getKeyguardCallback() {
    if (mUpdateMonitorCallback == null) {
        mUpdateMonitorCallback = new BaseKeyguardCallback();
    }
    return mUpdateMonitorCallback;
}

可以看到BaseKeyguardCallback是通过getKeyguardCallback()实例化的,继续查找getKeyguardCallback()是从哪里调用的

public KeyguardIndicationController(Context context,
        WakeLock.Builder wakeLockBuilder,
        KeyguardStateController keyguardStateController,
        StatusBarStateController statusBarStateController,
        KeyguardUpdateMonitor keyguardUpdateMonitor,
        DockManager dockManager,
        BroadcastDispatcher broadcastDispatcher,
        DevicePolicyManager devicePolicyManager,
        IBatteryStats iBatteryStats,
        UserManager userManager) {
...........
    mKeyguardUpdateMonitor.registerCallback(getKeyguardCallback());
    mKeyguardUpdateMonitor.registerCallback(mTickReceiver);
    mStatusBarStateController.addCallback(this);
    mKeyguardStateController.addCallback(this);
}

getKeyguardCallback()是通过KeyguardUpdateMonitor注册调用的。

KeyguardUpdateMonitor.java
public void registerCallback(KeyguardUpdateMonitorCallback callback) {
    ............
    mCallbacks.add(new WeakReference<>(callback));
    removeCallback(null); // remove unused references
    sendUpdates(callback);
}

registerCallback做了两个事情,一是把BaseKeyguardCallback添加到集合,二是调用sendUpdates。sendUpdates做了什么内容呢?

KeyguardUpdateMonitor.java
private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
    // Notify listener of the current state
    callback.onRefreshBatteryInfo(mBatteryStatus);
   ............
}

sendUpdates回调了onRefreshBatteryInfo,并把mBatteryStatus传入,再跟mBatteryStatus是从哪里设置的

KeyguardUpdateMonitor.java
private void handleBatteryUpdate(BatteryStatus status) {
    ........
    mBatteryStatus = status;
   ......
}
KeyguardUpdateMonitor.java
protected KeyguardUpdateMonitor(
        Context context,
        @Main Looper mainLooper,
        BroadcastDispatcher broadcastDispatcher,
        DumpManager dumpManager,
        RingerModeTracker ringerModeTracker,
        @Background Executor backgroundExecutor,
        StatusBarStateController statusBarStateController,
        LockPatternUtils lockPatternUtils) {
    .................
    mHandler = new Handler(mainLooper) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                ..........
                case MSG_BATTERY_UPDATE:
                    handleBatteryUpdate((BatteryStatus) msg.obj);
                    break;
    ................
}
KeyguardUpdateMonitor.java
protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        .........
        } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {

            final Message msg = mHandler.obtainMessage(
                    MSG_BATTERY_UPDATE, new BatteryStatus(intent));
            mHandler.sendMessage(msg);
        } else if (Intent.ACTION_SIM_STATE_CHANGED.equals(action)) {
    ..............
};

BatteryStatus最终是通过监听到Intent.ACTION_BATTERY_CHANGED的广播调用的。

BatteryStatus.java
public BatteryStatus(Intent batteryChangedIntent) {
    status = batteryChangedIntent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
    plugged = batteryChangedIntent.getIntExtra(EXTRA_PLUGGED, 0);
    level = batteryChangedIntent.getIntExtra(EXTRA_LEVEL, 0);
    health = batteryChangedIntent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
    present = batteryChangedIntent.getBooleanExtra(EXTRA_PRESENT, true);

    final int maxChargingMicroAmp = batteryChangedIntent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT,
            -1);
    int maxChargingMicroVolt = batteryChangedIntent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);

    if (maxChargingMicroVolt <= 0) {
        maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
    }
    if (maxChargingMicroAmp > 0) {
        // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
        // to maintain precision equally on both factors.
        maxChargingWattage = (maxChargingMicroAmp / 1000)
                * (maxChargingMicroVolt / 1000);
    } else {
        maxChargingWattage = -1;
    }
}

maxChargingWattage最大充电瓦数是通过maxChargingMicroAmp(电流)和maxChargingMicroVolt(电压)计算得出的。

至此,我们的的焦点转移到了Intent.ACTION_BATTERY_CHANGED广播的发出和广播携带的EXTRA_MAX_CHARGING_CURRENT、EXTRA_MAX_CHARGING_VOLTAGE两个参数上。

Intent.ACTION_BATTERY_CHANGED的广播是从BatteryService.java发出的。

BatteryService.java
private void sendBatteryChangedIntentLocked() {
    ...............
    intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mHealthInfo.maxChargingCurrent);
    intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mHealthInfo.maxChargingVoltage);
..........
    mHandler.post(() -> ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL));
}

BatteryManager.EXTRA_MAX_CHARGING_CURRENT和BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE这两个值是从mHealthInfo中得到的。继续看mHealthInfo是从哪里赋值的。

BatteryService.java
private void update(android.hardware.health.V2_1.HealthInfo info) {
   ..............
    synchronized (mLock) {
        if (!mUpdatesStopped) {
            mHealthInfo = info.legacy.legacy;
            mHealthInfo2p1 = info;
            // Process the new values.
            processValuesLocked(false);
            mLock.notifyAll(); // for any waiters on new info
............
}
BatteryService.java
private final class HealthHalCallback extends IHealthInfoCallback.Stub
        implements HealthServiceWrapper.Callback {
    @Override public void healthInfoChanged(android.hardware.health.V2_0.HealthInfo props) {
        ...............
        BatteryService.this.update(propsLatest);
    }

    @Override public void healthInfoChanged_2_1(android.hardware.health.V2_1.HealthInfo props) {
        BatteryService.this.update(props);
    }

healthInfoChanged_2_1是由Hal层的hardware\interfaces\health\utils\libhealth2impl\include\health2impl\Callback.h回调的。HAL是由不同厂商定制的,我们就不再往下跟了。

总结:充电的快慢的区分是在SettingsLib下配置的,充电的功率小于5W显示慢速充电,大于7.5W显示快速充电,在5W到7.5W之间显示正在充电,充电功率的值是进入到HAL层来获取。

本文是通过逆向思维的方法,从上往下去跟踪数据的获取/传入流程,最开始直接搜索显示的字符,快速找到调用的位置,这是在分析源码时很好的一个方法。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值