新的项目,手机充电的时候,systemui显示慢速充电。
通过电流计测量,充电电流为1.7A,电压5v,这个功率还挺高的,怎么就提示慢速充电了呢。
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);
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;
}
}
<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个月后,无奈。(前面的地址打不开了,换了一个源码的地址)
最大电流和最大电压的来源
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;
...
}
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>;
+};