电池信息上报框架

 /frameworks/base/services/core/java/com/android/server/BatteryService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

 public final class BatteryService extends SystemService {
    ... ...
    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;

            traceBegin("HealthUnregisterCallback");
            try {
                if (oldService != null) {
                    int r = oldService.unregisterCallback(this);
                    if (r != Result.SUCCESS) {
                        Slog.w(TAG, "health: cannot unregister previous callback: " +
                                Result.toString(r));
                    }
                }
            } catch (RemoteException ex) {
                Slog.w(TAG, "health: cannot unregister previous callback (transaction error): "
                            + ex.getMessage());
            } finally {
                traceEnd();
            }

            traceBegin("HealthRegisterCallback");
            try {
                int r = newService.registerCallback(this);  //this 就是 healthInfoChanged
                if (r != Result.SUCCESS) {
                    Slog.w(TAG, "health: cannot register callback: " + Result.toString(r));
                    return;
                }
                // registerCallback does NOT guarantee that update is called
                // immediately, so request a manual update here.
                newService.update();
            } catch (RemoteException ex) {
                Slog.e(TAG, "health: cannot register callback (transaction error): "
                        + ex.getMessage());
            } finally {
                traceEnd();
            }
        }
    }
    ... ...
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14

package android.hardware.health@2.0;

/**
 * IHealthInfoCallback is the callback interface to
 * {@link IHealthInfoBus.registerCallback}.
 */
interface IHealthInfoCallback {
    /**
     * An implementation of IHealthInfoBus must call healthInfoChanged on all
     * registered callbacks after health info changes.
     * @param info the updated HealthInfo
     */
    oneway healthInfoChanged(HealthInfo info);  //oneway时,远程调用((异步调用)不会阻塞;它只是发送事务数据并立即返回。
};

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

package android.hardware.health@2.0;

import @1.0::BatteryStatus;

import IHealthInfoCallback;

/**
 * IHealth manages health info and posts events on registered callbacks.
 */
interface IHealth {

    /**
     * Register a callback for any health info events.
     *
     * Registering a new callback must not unregister the old one; the old
     * callback remains registered until one of the following happens:
     * - A client explicitly calls {@link unregisterCallback} to unregister it.
     * - The client process that hosts the callback dies.
     *
     * @param callback the callback to register.
     * @return result SUCCESS if successful,
     *                UNKNOWN for other errors.
     */
    registerCallback(IHealthInfoCallback callback) generates (Result result);

    /**
     * Explicitly unregister a callback that is previously registered through
     * {@link registerCallback}.
     *
     * @param callback the callback to unregister
     * @return result SUCCESS if successful,
     *                NOT_FOUND if callback is not registered previously,
     *                UNKNOWN for other errors.
     */
    unregisterCallback(IHealthInfoCallback callback) generates (Result result);
    /**
     * Schedule update.
     *
     * When update() is called, the service must notify all registered callbacks
     * with the most recent health info.
     *
     * @return result SUCCESS if successful,
     *                CALLBACK_DIED if any registered callback is dead,
     *                UNKNOWN for other errors.
     */
    update() generates (Result result);
    ... ...
};

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

namespace android {
namespace hardware {
namespace health {
namespace V2_0 {
namespace implementation {

sp<Health> Health::instance_;

Health::Health(struct healthd_config* c) {
    // TODO(b/69268160): remove when libhealthd is removed.
    healthd_board_init(c);
    battery_monitor_ = std::make_unique<BatteryMonitor>();
    battery_monitor_->init(c);
}

// Methods from IHealth follow.
Return<Result> Health::registerCallback(const sp<IHealthInfoCallback>& callback) {
    if (callback == nullptr) {
        return Result::SUCCESS;
    }

    {
        std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
        callbacks_.push_back(callback);
        // unlock
    }

    auto linkRet = callback->linkToDeath(this, 0u /* cookie */);
    if (!linkRet.withDefault(false)) {
        LOG(WARNING) << __func__ << "Cannot link to death: "
                     << (linkRet.isOk() ? "linkToDeath returns false" : linkRet.description());
        // ignore the error
    }

    return updateAndNotify(callback);
}

bool Health::unregisterCallbackInternal(const sp<IBase>& callback) {
    if (callback == nullptr) return false;

    bool removed = false;
    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
    for (auto it = callbacks_.begin(); it != callbacks_.end();) {
        if (interfacesEqual(*it, callback)) {
            it = callbacks_.erase(it);
            removed = true;
        } else {
            ++it;
        }
    }
    (void)callback->unlinkToDeath(this).isOk();  // ignore errors
    return removed;
}

Return<Result> Health::unregisterCallback(const sp<IHealthInfoCallback>& callback) {
    return unregisterCallbackInternal(callback) ? Result::SUCCESS : Result::NOT_FOUND;
}

Return<Result> Health::update() {
    if (!healthd_mode_ops || !healthd_mode_ops->battery_update) {
        LOG(WARNING) << "health@2.0: update: not initialized. "
                     << "update() should not be called in charger";
        return Result::UNKNOWN;
    }

    // Retrieve all information and call healthd_mode_ops->battery_update, which calls
    // notifyListeners.

    battery_monitor_->updateValues();  //Android12 将update()分解成了updateValues()和battery_update(&props)

    const HealthInfo_1_0& health_info = battery_monitor_->getHealthInfo_1_0();  //Android12

    struct BatteryProperties props;  //Android12

    convertFromHealthInfo(health_info, &props);  //Android12

    healthd_mode_ops->battery_update(&props);  //Android12
    bool chargerOnline = battery_monitor_->update();  //Android11

    // adjust uevent / wakealarm periods
    healthd_battery_update_internal(chargerOnline);

    return Result::SUCCESS;
}

void Health::notifyListeners(HealthInfo* healthInfo) {
    std::vector<StorageInfo> info;
    get_storage_info(info);

    std::vector<DiskStats> stats;
    get_disk_stats(stats);

    int32_t currentAvg = 0;

    struct BatteryProperty prop;
    status_t ret = battery_monitor_->getProperty(BATTERY_PROP_CURRENT_AVG, &prop);
    if (ret == OK) {
        currentAvg = static_cast<int32_t>(prop.valueInt64);
    }

    healthInfo->batteryCurrentAverage = currentAvg;
    healthInfo->diskStats = stats;
    healthInfo->storageInfos = info;

    std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
    for (auto it = callbacks_.begin(); it != callbacks_.end();) {
        auto ret = (*it)->healthInfoChanged(*healthInfo);
        if (!ret.isOk() && ret.isDeadObject()) {
            it = callbacks_.erase(it);
        } else {
            ++it;
        }
    }

... ...
sp<IHealth> Health::initInstance(struct healthd_config* c) {
    if (instance_ == nullptr) {
        instance_ = new Health(c);
    }
    return instance_;
}

sp<Health> Health::getImplementation() {  //返回initInstance 实例化的Health
    CHECK(instance_ != nullptr);
    return instance_;
}

}  // namespace implementation
}  // namespace V2_0
}  // namespace health
}  // namespace hardware
}  // namespace android

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

healthd_mainloop 中调用epoll_wait(epollfd, events, eventct, timeout)等待uevent

uevent_event、wakealarm_event这两个事件最终都是调了healthd_battery_update{Health::getImplementation()->update();}

PS:Android 11以后相关流程有一些变化:

/hardware/interfaces/health/utils/libhealthloop/HealthLoop.cpp

void HealthLoop::UeventInit(void) {

 RegisterEvent(uevent_fd_, &HealthLoop::UeventEvent, EVENT_WAKEUP_FD)

  auto* event_handler = event_handlers_.emplace_back(std::make_unique<EventHandler>(EventHandler{this, fd, func})).get();

  struct epoll_event ev;

  ev.events = EPOLLIN;

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

  ev.data.ptr = reinterpret_cast<void*>(event_handler);

  epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev) == -1

}

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

class HealthLoopAdapter : public HealthLoop {

 protected:

  void ScheduleBatteryUpdate() override { Health::getImplementation()->update(); }

};

void HealthLoop::MainLoop(void) {

 epoll_wait(epollfd_, events, eventct, timeout);

  UeventEvent

   HalHealthLoop::ScheduleBatteryUpdate();  //hardware/interfaces/health/utils/libhealth2impl/HalHealthLoop.cpp

    Result res = service_->update();

    service_->getHealthInfo_2_1([this](auto res, const auto& health_info) {

     this->OnHealthInfoChanged(health_info);  //HalHealthLoop::OnHealthInfoChanged(const HealthInfo& health_info)

    });

HalHealthLoop::OnHealthInfoChanged

 set_charger_online(health_info);

 AdjustWakealarmPeriods(charger_online());

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

1
2
3

static void healthd_battery_update(void) {
    Health::getImplementation()->update();
}

 /hardware/interfaces/health/2.0/default/include/health2/Health.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#include <healthd/BatteryMonitor.h>

namespace android {
namespace hardware {
namespace health {
namespace V2_0 {
namespace implementation {

using V1_0::BatteryStatus;

using ::android::hidl::base::V1_0::IBase;

struct Health : public IHealth, hidl_death_recipient {
    public:
    ... ...
    private:
    std::unique_ptr<BatteryMonitor> battery_monitor_;
    ... ...
};

}  // namespace implementation
}  // namespace V2_0
}  // namespace health
}  // namespace hardware
}  // namespace android

#endif  // ANDROID_HARDWARE_HEALTH_V2_0_HEALTH_H

 /system/core/healthd/include/healthd/BatteryMonitor.h 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

namespace android {

class BatteryMonitor {
  public:

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

    BatteryMonitor();
    void init(struct healthd_config *hc);
    bool update(void);
    int getChargeStatus();
    status_t getProperty(int id, struct BatteryProperty *val);
    void dumpState(int fd);
    friend struct BatteryProperties getBatteryProperties(BatteryMonitor* batteryMonitor);

  private:
    struct healthd_config *mHealthdConfig;
    Vector<String8> mChargerNames;
    bool mBatteryDevicePresent;
    int mBatteryFixedCapacity;
    int mBatteryFixedTemperature;
    struct BatteryProperties props;

    int getBatteryStatus(const char* status);
    int getBatteryHealth(const char* status);
    int readFromFile(const String8& path, std::string* buf);
    PowerSupplyType readPowerSupplyType(const String8& path);
    bool getBooleanField(const String8& path);
    int getIntField(const String8& path);
};

}; // namespace android

 /system/core/healthd/BatteryMonitor.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

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

    initBatteryProperties(&props);  //HealthInfo_1_0& props = mHealthInfo->legacy.legacy;

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

    logthis = !healthd_board_battery_update(&props);

    if (logthis) {
        char dmesgline[256];
        size_t len;
        if (props.batteryPresent) {
            snprintf(dmesgline, sizeof(dmesgline),
                 "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
                 props.batteryLevel, props.batteryVoltage,
                 props.batteryTemperature < 0 ? "-" : "",
                 abs(props.batteryTemperature / 10),
                 abs(props.batteryTemperature % 10), props.batteryHealth,
                 props.batteryStatus);

            len = strlen(dmesgline);
            if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
                                " c=%d", props.batteryCurrent);
            }

            if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
                                " fc=%d", props.batteryFullCharge);
            }

            if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
                len += snprintf(dmesgline + len, sizeof(dmesgline) - len,
                                " cc=%d", props.batteryCycleCount);
            }
        } else {
            len = snprintf(dmesgline, sizeof(dmesgline),
                 "battery none");
        }

        snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s",
                 props.chargerAcOnline ? "a" : "",
                 props.chargerUsbOnline ? "u" : "",
                 props.chargerWirelessOnline ? "w" : "");

        KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
    }

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#include <health2/Health.h>

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

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

int health_service_main(const char* instance) {
    gInstanceName = instance;
    if (gInstanceName.empty()) {
        gInstanceName = "default";
    }
    healthd_mode_ops = &healthd_mode_service_2_0_ops;
    LOG(INFO) << LOG_TAG << gInstanceName << ": Hal starting main loop...";
    return healthd_main();
}

最后调用了Health.cpp的 notifyListeners()->healthInfoChanged()

而healthInfoChanged就是上层registerCallback(this)传下来的this指针

实际上就是回调Framework里面BatteryService的BatteryService.this.update(props)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值