/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)