Android手机提示正在慢速充电的解决方法

新的项目,手机充电的时候,systemui显示慢速充电。

通过电流计测量,充电电流为1.7A,电压5v,这个功率还挺高的,怎么就提示慢速充电了呢。

查看代码http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java

    protected String computePowerIndication() {
        if (mPowerCharged) {
            return mContext.getResources().getString(R.string.keyguard_charged);
        }

        final boolean hasChargingTime = mChargingTimeRemaining > 0;
        int chargingId;
        if (mPowerPluggedInWired) {
            switch (mChargingSpeed) {
                case BatteryStatus.CHARGING_FAST:
                    chargingId = hasChargingTime
                            ? R.string.keyguard_indication_charging_time_fast
                            : R.string.keyguard_plugged_in_charging_fast;
                    break;
                case BatteryStatus.CHARGING_SLOWLY:
                    chargingId = hasChargingTime
                            ? R.string.keyguard_indication_charging_time_slowly
                            : R.string.keyguard_plugged_in_charging_slowly;
                    break;
                default:
                    chargingId = hasChargingTime
                            ? R.string.keyguard_indication_charging_time
                            : R.string.keyguard_plugged_in;
                    break;
            }
        } else {
            chargingId = hasChargingTime
                    ? R.string.keyguard_indication_charging_time_wireless
                    : R.string.keyguard_plugged_in_wireless;
        }
mChargingSpeed = status.getChargingSpeed(mContext);

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/packages/SettingsLib/src/com/android/settingslib/fuelgauge/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;
    }
    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);

        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;
        }
    }

 http://aospxref.com/android-11.0.0_r21/xref/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>

也就是低于5w显示慢速充电,高于7.5w显示快速充电,大于5w而小于7.5w或者获取不到最大电流值显示正在充电。

当然分析的是Android原生代码,mtk应该对这一块作了定制,要下周到公司look下源码了。

有空再来分析已是1个月后,无奈。(前面的地址打不开了,换了一个源码的地址)

最大电流和最大电压的来源

https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/services/core/java/com/android/server/BatteryService.java

intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mHealthInfo.maxChargingCurrent);
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mHealthInfo.maxChargingVoltage);

最终到https://www.androidos.net.cn/android/10.0.0_r6/xref/system/core/healthd/BatteryMonitor.cpp,这块不好理解,可参考 https://blog.csdn.net/qq759981398/article/details/73155782

#define POWER_SUPPLY_SUBSYSTEM "power_supply"
#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
#define MILLION 1.0e6
#define DEFAULT_VBUS_VOLTAGE 5000000  //底层获取的电压是uV 电流是uA

static void initBatteryProperties(BatteryProperties* props) {
    ...
    props->maxChargingCurrent = 0;
    props->maxChargingVoltage = 0;
    ...
}

bool BatteryMonitor::update(void) {
	
	     double MaxPower = 0;
            path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, mChargerNames[i].string());
            int ChargingCurrent =(access(path.string(), R_OK) == 0) ? getIntField(path) : 0;

            path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,mChargerNames[i].string());
            int ChargingVoltage =(access(path.string(), R_OK) == 0) ? getIntField(path) :DEFAULT_VBUS_VOLTAGE;

            double power = ((double)ChargingCurrent / MILLION) *((double)ChargingVoltage / MILLION);
            if (MaxPower < power) {
                props.maxChargingCurrent = ChargingCurrent;
                props.maxChargingVoltage = ChargingVoltage;
                MaxPower = power;
            }
}

再看下mChargerNames的定义

void BatteryMonitor::init(struct healthd_config *hc) {
    String8 path;
    char pval[PROPERTY_VALUE_MAX];

    mHealthdConfig = hc;
    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
    if (dir == NULL) {
        KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
    } else {
        struct dirent* entry;

        while ((entry = readdir(dir.get()))) {
            const char* name = entry->d_name;
            std::vector<String8>::iterator itIgnoreName;

         
            path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
            switch(readPowerSupplyType(path)) {
            case ANDROID_POWER_SUPPLY_TYPE_AC:
            case ANDROID_POWER_SUPPLY_TYPE_USB:
            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
                path.clear();
                path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
                if (access(path.string(), R_OK) == 0)
                    mChargerNames.add(String8(name));
                break;
... 
}

https://www.androidos.net.cn/android/10.0.0_r6/xref/system/core/healthd/include/healthd/BatteryMonitor.h

   enum PowerSupplyType {
        ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0,
        ANDROID_POWER_SUPPLY_TYPE_AC,
        ANDROID_POWER_SUPPLY_TYPE_USB,
        ANDROID_POWER_SUPPLY_TYPE_WIRELESS,
        ANDROID_POWER_SUPPLY_TYPE_BATTERY
    };

遍历sys/class/power_supply里每一个文件夹,如果文件夹里有type节点(且值为1,2,3)皆且有online节点,则判定为mChargerNames

于是去查找该节点,刚好有一个/sys/class/power_supply/usb,看下获取电流电压的实现

static int mt_usb_get_property(struct power_supply *psy,
	enum power_supply_property psp, union power_supply_propval *val)
{
	struct mtk_charger_type *info;

	info = (struct mtk_charger_type *)power_supply_get_drvdata(psy);

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		if ((info->type == POWER_SUPPLY_USB_TYPE_SDP) ||
			(info->type == POWER_SUPPLY_USB_TYPE_CDP))
			val->intval = 1;
		else
			val->intval = 0;
		break;
	case POWER_SUPPLY_PROP_CURRENT_MAX:
		val->intval = 500000;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
		val->intval = 5000000;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

 你说为什么这么奇怪,mtk原始的代码固定了。也就是5x0.5=2.5w,那当然显示慢速充电了。

再看下有如下代码

if (info->bc12_active) {
	info->usb_psy = power_supply_register(&pdev->dev,&info->usb_desc, &info->usb_cfg);
}

如果dtsi有配置bc12_active的值为1,才会跑到这段代码,该值默认是0,但我使用的工程对应该值为1,于是跑到了。

如果该值默认是0,那么将获取不到该节点,按上面的代码,默认电压是0A,默认电流是0A,提示语就会变成正在充电。

至于bc12_active配置0有没有问题,还要再考虑下。

今天再来看调试信息,发现符合条件的mChargerNames有两个,分别是mt6370_pmu_charger和mtk_charger_type
看下mt6370的获取电压和电流的方式

chg_data->psy_desc.type 不会是POWER_SUPPLY_TYPE_USB,val->intval不会赋值
static int mt6370_charger_get_property(struct power_supply *psy,enum power_supply_property psp,union power_supply_propval *val)
{
	int ret = 0;
	...
	case POWER_SUPPLY_PROP_CURRENT_MAX:
		if (chg_data->psy_desc.type == POWER_SUPPLY_TYPE_USB)
			val->intval = 500000;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
		if (chg_data->psy_desc.type == POWER_SUPPLY_TYPE_USB)
			val->intval = 5000000;
		break;
	...
	return ret;
}

按如下修改把mChargerNames改成1个,系统就提示正在充电了。

-&mtk_gauge {
-    charger = <&mtk_charger_type>;
-};

-&charger {
-    charger = <&mtk_charger_type>;
-};

-&usb {
-    charger = <&mtk_charger_type>;
-}

-&mtk_charger_type {
-       bc12_active = <1>;
-}

+&mt6370_chg {
+    bc12_sel = <1>;
+};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值