展锐USB充电图标更新流程

介绍

power_supply 目录下online节点是用于判断是否插入battery、ac(外部电源) 和USB 的节点,目录在sys/class/power_supply/battery(ac、usb)/online,主要用于在StatusBar 上显示充电的闪电图标。 

展锐USB充电图标更新流程_第1张图片

展锐USB充电图标更新流程_第2张图片

SystemUI层介绍

流程介绍

在SystemUI 中控制充电图标的位置在BatteryMeterDrawable.java 类中实现的

SystemUI/src/com/sprd/battery/BatteryMeterDrawable.java

@Override
public void draw(Canvas c) {
    ...
    // 这里表示有任何一个适配器(AC/USB)插入(power_supply目录下的online 节点值为1),并且状态是正在充电中(power_supply目录下status 为Charging 状态, status 的值为BATTERY_STATUS_CHARGING)
    if (plugged && level != 100
                && (mTracker.status == BatteryManager.BATTERY_STATUS_CHARGING || mCharging)) {
    ...
}

这个类相当于一个自定义的充电图标控件,在第一次加载或者调用了invalidateSelf() 方法后会调用draw() 方法重新绘制图标。

整个SystemUI 更新充电图标的流程为:

  1. BatteryServer 发送ACTION_BATTERY_CHANGED 广播向广播接收器提示Battery 发生了变化
  2. BatteryControllerImpl.java接收到此广播,调用fireBatteryLevelChanged() 方法向注册了BatteryStateChangeCallback 类回调 onBatteryLevelChanged() 方法
  3. BatteryMeterDrawable.java 调用onBatteryLevelChanged() 方法后更新充电状态,并且调用postInvalidate() 方法重绘图标

代码流程

1. BatteryService 服务发送电池更新的广播

frameworks/base/services/core/java/com/android/server/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(props);
    }
    ...
}

// 由Health::notifyListeners 调用过来的
private void update(android.hardware.health.V2_0.HealthInfo info) {
    synchronized (mLock) {
        mRealBatteryLevel = info.legacy.batteryLevel;
        if (!mUpdatesStopped) {
            mHealthInfo = info.legacy;
            processValuesLocked(false);
            mLock.notifyAll();
        } else {
            copy(mLastHealthInfo, info.legacy);
        }
    }
}

private void processValuesLocked(boolean force) {
    ...
    sendBatteryChangedIntentLocked(); // 发送Intent.ACTION_BATTERY_CHANGED 广播
    ...
}


private void sendBatteryChangedIntentLocked() {
    //  Pack up the values and broadcast them to everyone
    final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
            | Intent.FLAG_RECEIVER_REPLACE_PENDING);
    ...
    mHandler.post(() -> ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL));
}

2. BatteryControllerImpl 调用流程

BatteryControllerImpl类继承了BroadcastReceiver 类,并且监听了ACTION_BATTERY_CHANGED 广播,当收到ACTION_BATTERY_CHANGED广播后调用fireBatteryLevelChanged() 方法调用注册的回调方法

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java

@Override
public void onReceive(final Context context, Intent intent) {
    ...
    final String action = intent.getAction();
    if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
        ...
        fireBatteryLevelChanged();
        ...
    }
    ...                                            
}

protected void fireBatteryLevelChanged() {
    synchronized (mChangeCallbacks) {
        final int N = mChangeCallbacks.size();
        for (int i = 0; i < N; i++) {
            // 调用所有注册到mChangeCallbacks中的BatteryStateChangeCallback类回调函数
            mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
        }
    }
}


// BatteryMeterDrawable 会通过此方法添加BatteryStateChangeCallback 回调函数
@Override
public void addCallback(BatteryController.BatteryStateChangeCallback cb) {
    synchronized (mChangeCallbacks) {
        mChangeCallbacks.add(cb);
    }
    if (!mHasReceivedBattery) return;
    cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
    cb.onPowerSaveChanged(mPowerSave);
}

3. BatteryMeterDrawable 调用介绍

frameworks/base/packages/SystemUI/src/com/sprd/battery/BatteryMeterDrawable.java

public void startListening() {
    ...
    // 这里向BatteryControllerImpl 类注册了回调
    mBatteryController.addCallback(this);   
    ...
}

@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
    Log.d(TAG, "onBatteryLevelChanged level="+level+",pluggedIn="+pluggedIn+",charging="+charging);
    mLevel = level;
    mPluggedIn = pluggedIn; // 更新充电器插入状态
    mCharging = charging;
    postInvalidate(); // 重绘当前控件
}

Framework 层介绍

frameworks/base/services/core/java/com/android/server/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(props);
    }
    // on new service registered
    @Override public void onRegistration(IHealth oldService, IHealth newService,
            String instance) {
        if (newService == null) return;
        ...
        try {
            int r = newService.registerCallback(this); // 向IHealth hal 服务注册回调
            if (r != Result.SUCCESS) {
                Slog.w(TAG, "health: cannot register callback: " + Result.toString(r));
                return;
            }
            newService.update();
        ...
    }
}

@Override
public void onStart() {
    // 服务启动的时候会调用registerHealthCallback() 方法注册服务
    registerHealthCallback();
    mBinderService = new BinderService();
    publishBinderService("battery", mBinderService);
    mBatteryPropertiesRegistrar = new BatteryPropertiesRegistrar();
    publishBinderService("batteryproperties", mBatteryPropertiesRegistrar);
    publishLocalService(BatteryManagerInternal.class, new LocalService());
}

// 这里调用mHealthServiceWrapper.init() 方法初始化mHealthServiceWrapper
private void registerHealthCallback() {
    mHealthServiceWrapper = new HealthServiceWrapper();
    mHealthHalCallback = new HealthHalCallback();
    // IHealth is lazily retrieved.
    try {
        mHealthServiceWrapper.init(mHealthHalCallback,
                new HealthServiceWrapper.IServiceManagerSupplier() {},
                new HealthServiceWrapper.IHealthSupplier() {});
    ...
}

static final class HealthServiceWrapper {
    void init(Callback callback,
                IServiceManagerSupplier managerSupplier,
                IHealthSupplier healthSupplier)
            throws RemoteException, NoSuchElementException, NullPointerException {
        if (callback == null || managerSupplier == null || healthSupplier == null)
            throw new NullPointerException();
    
        IServiceManager manager;
    
        mCallback = callback;
        mHealthSupplier = healthSupplier;
    
        IHealth newService = null;
        for (String name : sAllInstances) {
            traceBegin("HealthInitGetService_" + name);
            try {
                newService = healthSupplier.get(name); // 获取IHealth hal 服务
            } catch (NoSuchElementException ex) {
                /* ignored, handled below */
            } finally {
                traceEnd();
            }
            if (newService != null) {
                mInstanceName = name;
                mLastService.set(newService);
                break;
            }
        }
        ...
        mCallback.onRegistration(null, newService, mInstanceName); // 调用onRegistration() 回调函数
        mHandlerThread.start();
        try {
            managerSupplier.get().registerForNotifications(
                    IHealth.kInterfaceName, mInstanceName, mNotification);
        ...
    }
    ...
}

Hal层介绍

在BatteryService.java 中使用到的IHealthInfoCallback和IHealth 都是Hal 服务,代码路径为:

  • hardware/interfaces/health/2.0/IHealth.hal
  • hardware/interfaces/health/2.0/IHealthInfoCallback.hal

Hal 服务实现路径为:

  • hardware/interfaces/health/2.0/default/Health.cpp
  • hardware/interfaces/health/2.0/default/HealthImplDefault.cpp

在BatteryService 中通过newService.registerCallback(this) 方法向IHealth 中注册了回调

接着查看我们Health::registerCallback() 方法

hardware/interfaces/health/2.0/default/Health.cpp

Return Health::registerCallback(const sp& callback) {
    ...
    {
        std::lock_guard lock(callbacks_lock_);
        callbacks_.push_back(callback);  // 将callback 放到callbacks_ 中
    }
    ...
    return updateAndNotify(callback);
}

Return Health::updateAndNotify(const sp& callback) {
    std::lock_guard lock(callbacks_lock_);
    std::vector> storedCallbacks{std::move(callbacks_)};
    callbacks_.clear();
    if (callback != nullptr) {
        callbacks_.push_back(callback);
    }
    Return result = update(); // 接着会调用update() 方法更新电池状态信息
    callbacks_ = std::move(storedCallbacks);
    return result;
}

Return Health::update() {
    if (!healthd_mode_ops || !healthd_mode_ops->battery_update) {
        return Result::UNKNOWN;
    }
    bool chargerOnline = battery_monitor_->update(); // 调用BatteryMonitor::update() 方法更新电池状态
    healthd_battery_update_internal(chargerOnline);
    return Result::SUCCESS;
}

在之后会调用到BatteryMonitor::update() 方法中更新状态并上发状态到Framework 中

system/core/healthd/BatteryMonitor.cpp

bool BatteryMonitor::update(void) {
    bool logthis;

    initBatteryProperties(&props);

    if (!mHealthdConfig->batteryPresentPath.isEmpty())
        props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
    else
        props.batteryPresent = mBatteryDevicePresent;

    props.batteryLevel = mBatteryFixedCapacity ?
        mBatteryFixedCapacity :
        getIntField(mHealthdConfig->batteryCapacityPath);
    props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;

    if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
        props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath) / 1000;

    if (!mHealthdConfig->batteryFullChargePath.isEmpty())
        props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath);

    if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
        props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);

    if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
        props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);

    props.batteryTemperature = mBatteryFixedTemperature ?
        mBatteryFixedTemperature :
        getIntField(mHealthdConfig->batteryTemperaturePath);

    std::string buf;

    if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
        props.batteryStatus = getBatteryStatus(buf.c_str());

    if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
        props.batteryHealth = getBatteryHealth(buf.c_str());

    if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
        props.batteryTechnology = String8(buf.c_str());

    double MaxPower = 0;

    for (size_t i = 0; i < mChargerNames.size(); i++) {
        String8 path;
        path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
                          mChargerNames[i].string());
        if (getIntField(path)) {
            path.clear();
            path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
                              mChargerNames[i].string());
            switch(readPowerSupplyType(path)) {
            case ANDROID_POWER_SUPPLY_TYPE_AC:
                props.chargerAcOnline = true;
                break;
            case ANDROID_POWER_SUPPLY_TYPE_USB:
                props.chargerUsbOnline = true;
                break;
            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
                props.chargerWirelessOnline = true;
                break;
            default:
                KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
                             mChargerNames[i].string());
            }
            path.clear();
            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.clear();
            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;
            }
        }
    }

    ...

    healthd_mode_ops->battery_update(&props);
    return props.chargerAcOnline | props.chargerUsbOnline |
            props.chargerWirelessOnline;
}

在update() 方法里会读取/sys/class/power_supply 目录下的所有目录和节点,结果保存在props 中,通过healthd_mode_ops->battery_update() 方法上传到FW 层

healthd_mode_ops->battery_update() 方法在HealthServiceCommon.cpp 中做了初始化

hardware/interfaces/health/2.0/utils/libhealthservice/HealthServiceCommon.cpp

static struct healthd_mode_ops healthd_mode_service_2_0_ops = {
    .init = healthd_mode_service_2_0_init,
    .preparetowait = healthd_mode_service_2_0_preparetowait,
    .heartbeat = healthd_mode_service_2_0_heartbeat,
    .battery_update = healthd_mode_service_2_0_battery_update,
};

void healthd_mode_service_2_0_battery_update(struct android::BatteryProperties* prop) {
    HealthInfo info;
    convertToHealthInfo(prop, info.legacy);
    Health::getImplementation()->notifyListeners(&info);
}

在调用healthd_mode_ops->battery_update() 时,会调用到HealthServiceCommon:: healthd_mode_service_2_0_battery_update() 方法中,该方法会调用Health::getImplementation()->notifyListeners() 方法将prop数据传给Health.cpp 中,由Health调用notifyListeners() 方法调用从BatteryService 注册的回调实现数据上传给BatteryService 中

hardware/interfaces/health/2.0/default/Health.cpp

void Health::notifyListeners(HealthInfo* healthInfo) {
    ...
    std::lock_guard lock(callbacks_lock_);
    for (auto it = callbacks_.begin(); it != callbacks_.end();) {
        auto ret = (*it)->healthInfoChanged(*healthInfo); // 这里就会调用BatteryService 里的healthInfoChanged() 方法
        if (!ret.isOk() && ret.isDeadObject()) {
            it = callbacks_.erase(it);
        } else {
            ++it;
        }
    }
}

在此方法中会调用BatteryService 的回调方法healthInfoChanged() 将数据传给BatteryService

Kernel 层分析

在Kernel层,如果power_supply目录下的节点更新了,会通过uenent 的方法通知上层节点修改了,接受通知的地方在healthd_common::healthd_mainloop() 中定义的

healthd_common::healthd_mainloop() 方法的初始化流程:

HealthServiceDefault::main() ->HealthServiceCommon::health_service_main() -> healthd_common::healthd_main() -> healthd_common::healthd_mainloop()

hardware/interfaces/health/2.0/default/healthd_common.cpp

static void healthd_mainloop(void) {
    int nevents = 0;
    while (1) {
        struct epoll_event events[eventct];
        int timeout = awake_poll_interval;
        int mode_timeout;

        /* Don't wait for first timer timeout to run periodic chores */
        if (!nevents) periodic_chores();

        healthd_mode_ops->heartbeat();

        mode_timeout = healthd_mode_ops->preparetowait();
        if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout)) timeout = mode_timeout;
        nevents = epoll_wait(epollfd, events, eventct, timeout);
        if (nevents == -1) {
            if (errno == EINTR) continue;
            KLOG_ERROR(LOG_TAG, "healthd_mainloop: epoll_wait failed\n");
            break;
        }

        for (int n = 0; n < nevents; ++n) {
            if (events[n].data.ptr) (*(void (*)(int))events[n].data.ptr)(events[n].events);
        }
    }

    return;
}

healthd_mainloop() 方法会通过一直循环接收uevent 事件,当接受了事件,则调用events[n].data.ptr 方法

hardware/interfaces/health/2.0/default/healthd_common.cpp

static int healthd_init() {
    epollfd = epoll_create(EPOLL_CLOEXEC);
    if (epollfd == -1) {
        KLOG_ERROR(LOG_TAG, "epoll_create1 failed; errno=%d\n", errno);
        return -1;
    }

    healthd_mode_ops->init(&healthd_config);
    wakealarm_init();
    uevent_init();

    return 0;
}


static void uevent_init(void) {
    uevent_fd = uevent_open_socket(64 * 1024, true);

    if (uevent_fd < 0) {
        KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
        return;
    }

    fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
    if (healthd_register_event(uevent_fd, uevent_event, EVENT_WAKEUP_FD))
        KLOG_ERROR(LOG_TAG, "register for uevent events failed\n");
}

int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
    struct epoll_event ev;

    ev.events = EPOLLIN;

    if (wakeup == EVENT_WAKEUP_FD) ev.events |= EPOLLWAKEUP;

    ev.data.ptr = (void*)handler;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        KLOG_ERROR(LOG_TAG, "epoll_ctl failed; errno=%d\n", errno);
        return -1;
    }

    eventct++;
    return 0;
}

从上面可以看到data.ptr 为uevent_event 方法

hardware/interfaces/health/2.0/default/healthd_common.cpp

#define UEVENT_MSG_LEN 2048
static void uevent_event(uint32_t /*epevents*/) {
    char msg[UEVENT_MSG_LEN + 2];
    char* cp;
    int n;

    n = uevent_kernel_multicast_recv(uevent_fd, msg, UEVENT_MSG_LEN);
    if (n <= 0) return;
    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
        return;

    msg[n] = '\0';
    msg[n + 1] = '\0';
    cp = msg;

    while (*cp) {
        if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) {
            healthd_battery_update(); // 通知Monitor 更新Battery 信息
            break;
        }

        /* advance to after the next \0 */
        while (*cp++)
            ;
    }
}

static void healthd_battery_update(void) {
    Health::getImplementation()->update(); // 调用Health.cpp 里面的update() 方法
}
bsp/kernel/kernel4.14/drivers/power/supply/charger-manager.c

static int charger_manager_probe(struct platform_device *pdev)
{
    ...
    charger_manager_policy_init(cm);
    ...
}


static int charger_manager_policy_init(struct charger_manager *cm)
{
    ...
    INIT_DELAYED_WORK(&(cm->policy.usb_changed_work), policy_usb_change_handler_work);
    ...
    cm->policy.usb_notify.notifier_call = policy_usb_change_callback; // 这里会注册usb 通知,当插入USB时,会调用notifier_call() 方法
    ret = usb_register_notifier(cm->policy.usb_phy, &cm->policy.usb_notify);
    ...
}

static int policy_usb_change_callback(struct notifier_block *nb,
                       unsigned long limit, void *data)
{
    struct charger_policy *info =
        container_of(nb, struct charger_policy, usb_notify);
    info->limit = limit;
    vote_debug("policy_usb_change_callback: %d\n", (uint)limit);
    schedule_delayed_work(&info->usb_changed_work, msecs_to_jiffies(100)); // 接着触发usb_changed_work() 方法, 即policy_usb_change_handler_work()
    return NOTIFY_OK;
}

static void policy_usb_change_handler_work(struct work_struct *work)
{
    ...
    cm_notify_event(info->hook_psy, CM_EVENT_CHG_START_STOP, NULL);
    ...
}

static void cm_notify_type_handle(struct charger_manager *cm, enum cm_event_types type, char *msg)
{
    ...
    power_supply_changed(cm->charger_psy);
}

power_supply_changed() 方法在power_supply_core.c 定义的

bsp/kernel/kernel4.14/drivers/power/supply/power_supply_core.c

void power_supply_changed(struct power_supply *psy)
{
    unsigned long flags;
    dev_dbg(&psy->dev, "%s\n", __func__);

    spin_lock_irqsave(&psy->changed_lock, flags);
    psy->changed = true;
    pm_stay_awake(&psy->dev);
    spin_unlock_irqrestore(&psy->changed_lock, flags);
    schedule_work(&psy->changed_work);
}
EXPORT_SYMBOL_GPL(power_supply_changed);

之后会调用power_supply_changed_work() 方法


static void power_supply_changed_work(struct work_struct *work)
{
    unsigned long flags;
    struct power_supply *psy = container_of(work, struct power_supply,
                        changed_work);

    dev_dbg(&psy->dev, "%s\n", __func__);

    spin_lock_irqsave(&psy->changed_lock, flags);

    if (likely(psy->changed)) {
        psy->changed = false;
        spin_unlock_irqrestore(&psy->changed_lock, flags);
        class_for_each_device(power_supply_class, NULL, psy,
                      __power_supply_changed_work);
        power_supply_update_leds(psy);
        // 通知注册在power_supply_notifier通知链上的所有的通知回调函数,并将psy传递过去
        atomic_notifier_call_chain(&power_supply_notifier,
                PSY_EVENT_PROP_CHANGED, psy);
        kobject_uevent(&psy->dev.kobj, KOBJ_CHANGE); // 这里会通过uevent 的方式通知用户空间
        spin_lock_irqsave(&psy->changed_lock, flags);
    }

    if (likely(!psy->changed))
        pm_relax(&psy->dev);
    spin_unlock_irqrestore(&psy->changed_lock, flags);
}
bsp/kernel/kernel4.14/lib/kobject_uevent.c

int kobject_uevent(struct kobject *kobj, enum kobject_action action)
{
    return kobject_uevent_env(kobj, action, NULL);
}
EXPORT_SYMBOL_GPL(kobject_uevent);

int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
               char *envp_ext[])
{
    ...
    if (uevent_ops && uevent_ops->uevent) {
        retval = uevent_ops->uevent(kset, kobj, env);
        if (retval) {
            pr_debug("kobject: '%s' (%p): %s: uevent() returned "
                 "%d\n", kobject_name(kobj), kobj,
                 __func__, retval);
            goto exit;
        }
    }
    ...
}

uevent_ops->uevent() 方法将会调用power_supply_sysfs::power_supply_uevent() 方法,定义的位置在power_supply_class_init() 方法中

bsp/kernel/kernel4.14/drivers/power/supply/power_supply_core.c

static int __init power_supply_class_init(void)
{
    power_supply_class = class_create(THIS_MODULE, "power_supply");
    ...
    power_supply_class->dev_uevent = power_supply_uevent; // 这个power_supply_uevent方法会去读取power_supply 目录下的所有节点信息
    ...
}

kobject_uevent_env() 函数的主要功能是根据参数组合一个字符串并发送。一个典型的字符串如下:

ACTION=change DEVPATH=/devices/qpnp-charger-eab16c00/power_supply/battery

SUBSYSTEM=power_supply POWER_SUPPLY_NAME=battery

POWER_SUPPLY_STATUS=Charging POWER_SUPPLY_HEALTH=Good

POWER_SUPPLY_PRESENT=1 POWER_SUPPLY_VOLTAGE_NOW=3751000

POWER_SUPPLY_VOLTAGE_AVG=3751000 POWER_SUPPLY_CAPACITY=14

POWER_SUPPLY_ONLINE=1 POWER_SUPPLY_CHARGE_FULL=2000000

POWER_SUPPLY_CONSTANT_CHARGE_CURRENT=500000

POWER_SUPPLY_INPUT_CURRENT_LIMIT=500000

POWER_SUPPLY_CURRENT_NOW=261000

POWER_SUPPLY_CURRENT_AVG=261000

POWER_SUPPLY_CHARGE_COUNTER=260000

POWER_SUPPLY_CHARGE_CONTROL_LIMIT=1000000

POWER_SUPPLY_CHARGE_FULL_DESIGN=2000000

POWER_SUPPLY_CAPACITY_RAW=13 POWER_SUPPLY_VOLTAGE_OCV=3675357

POWER_SUPPLY_VOLTAGE_MAX=4350000

POWER_SUPPLY_CURRENT_COUNTER_MBTK=261175

POWER_SUPPLY_SET_SHIP_MODE=-1 POWER_SUPPLY_TECHNOLOGY=Li-ion

POWER_SUPPLY_CHARGING_ENABLED=1

POWER_SUPPLY_BATTERY_CHARGING_ENABLED=1

POWER_SUPPLY_TIME_TO_FULL_NOW=12528

POWER_SUPPLY_CURRENT_NOW=261000 POWER_SUPPLY_TEMP=307

在kobject_uevent_env() 方法中,retval = add_uevent_var(env, "%s", envp_ext[i]);//将kernel想要发送的状态信息存储起来。

最终是通过netlink_broadcast_filtered向用户空间发送了uevent信息。

发送了uevent 消息,总会有一个地方接收,那么接收这个uevent 信息的在方法uevent_event里

hardware/interfaces/health/2.0/default/healthd_common.cpp

#define UEVENT_MSG_LEN 2048
static void uevent_event(uint32_t /*epevents*/) {
    char msg[UEVENT_MSG_LEN + 2];
    char* cp;
    int n;

    n = uevent_kernel_multicast_recv(uevent_fd, msg, UEVENT_MSG_LEN);
    if (n <= 0) return;
    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
        return;

    msg[n] = '\0';
    msg[n + 1] = '\0';
    cp = msg;

    while (*cp) {
        if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) {
            healthd_battery_update();
            break;
        }

        /* advance to after the next \0 */
        while (*cp++)
            ;
    }
}

通过uevent_kernel_multicast_recv() 方法获取uevent 通知,在通过与 "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM 进行比较,判断是否是来自power_supply子系统的,如果是,则调用healthd_battery_update() 方法向上层发送Battery 信息。

参考

  •  Android Healthd电池服务分析
  • 基于Android Q电池服务分析
  • Battery监听流程
  • Linux下的power_supply小析
  • linux驱动DEVICE_ATTR使用、热插拔上报uevent及驱动启动一个c语言用语
  • 基于power supply信息传递的uevent机制
  • power supply是如何上报电池信息的 ​

你可能感兴趣的:(Android,电源,android,充电状态上报流程,Battery,power_supply)