healthd: Move power_supply attribute paths to healthd_config

Allow health HAL to select specific paths to be used, overriding
default search for arbitrary power supplies with the named paths.

Change-Id: I5f724739f58ef56087ab592b7403fc083db8f173
This commit is contained in:
Todd Poynor 2013-08-12 17:03:35 -07:00
parent d65104ca31
commit f5d3012d2c
4 changed files with 144 additions and 81 deletions

View File

@ -181,33 +181,33 @@ bool BatteryMonitor::update(void) {
props.batteryCurrentNow = INT_MIN;
props.batteryChargeCounter = INT_MIN;
if (!mBatteryPresentPath.isEmpty())
props.batteryPresent = getBooleanField(mBatteryPresentPath);
if (!mHealthdConfig->batteryPresentPath.isEmpty())
props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
else
props.batteryPresent = true;
props.batteryLevel = getIntField(mBatteryCapacityPath);
props.batteryVoltage = getIntField(mBatteryVoltagePath) / 1000;
props.batteryLevel = getIntField(mHealthdConfig->batteryCapacityPath);
props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
if (!mBatteryCurrentNowPath.isEmpty())
props.batteryCurrentNow = getIntField(mBatteryCurrentNowPath);
if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
props.batteryCurrentNow = getIntField(mHealthdConfig->batteryCurrentNowPath);
if (!mBatteryChargeCounterPath.isEmpty())
props.batteryChargeCounter = getIntField(mBatteryChargeCounterPath);
if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);
props.batteryTemperature = getIntField(mBatteryTemperaturePath);
props.batteryTemperature = getIntField(mHealthdConfig->batteryTemperaturePath);
const int SIZE = 128;
char buf[SIZE];
String8 btech;
if (readFromFile(mBatteryStatusPath, buf, SIZE) > 0)
if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0)
props.batteryStatus = getBatteryStatus(buf);
if (readFromFile(mBatteryHealthPath, buf, SIZE) > 0)
if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0)
props.batteryHealth = getBatteryHealth(buf);
if (readFromFile(mBatteryTechnologyPath, buf, SIZE) > 0)
if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0)
props.batteryTechnology = String8(buf);
unsigned int i;
@ -252,7 +252,7 @@ bool BatteryMonitor::update(void) {
abs(props.batteryTemperature % 10), props.batteryHealth,
props.batteryStatus);
if (!mBatteryCurrentNowPath.isEmpty()) {
if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
char b[20];
snprintf(b, sizeof(b), " c=%d", props.batteryCurrentNow / 1000);
@ -272,9 +272,10 @@ bool BatteryMonitor::update(void) {
props.chargerWirelessOnline;
}
void BatteryMonitor::init(bool nosvcmgr) {
void BatteryMonitor::init(struct healthd_config *hc, bool nosvcmgr) {
String8 path;
mHealthdConfig = hc;
DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);
if (dir == NULL) {
KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
@ -302,59 +303,92 @@ void BatteryMonitor::init(bool nosvcmgr) {
break;
case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
path.clear();
path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mBatteryStatusPath = path;
path.clear();
path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mBatteryHealthPath = path;
path.clear();
path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mBatteryPresentPath = path;
path.clear();
path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mBatteryCapacityPath = path;
path.clear();
path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0) {
mBatteryVoltagePath = path;
} else {
if (mHealthdConfig->batteryStatusPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/batt_vol", POWER_SUPPLY_SYSFS_PATH, name);
path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mBatteryVoltagePath = path;
mHealthdConfig->batteryStatusPath = path;
}
path.clear();
path.appendFormat("%s/%s/current_now", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mBatteryCurrentNowPath = path;
path.clear();
path.appendFormat("%s/%s/charge_counter", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mBatteryChargeCounterPath = path;
path.clear();
path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0) {
mBatteryTemperaturePath = path;
} else {
if (mHealthdConfig->batteryHealthPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/batt_temp", POWER_SUPPLY_SYSFS_PATH, name);
path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mBatteryTemperaturePath = path;
mHealthdConfig->batteryHealthPath = path;
}
if (mHealthdConfig->batteryPresentPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryPresentPath = path;
}
if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryCapacityPath = path;
}
if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/voltage_now",
POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0) {
mHealthdConfig->batteryVoltagePath = path;
} else {
path.clear();
path.appendFormat("%s/%s/batt_vol",
POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryVoltagePath = path;
}
}
if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/current_now",
POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryCurrentNowPath = path;
}
if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/charge_counter",
POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryChargeCounterPath = path;
}
if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
name);
if (access(path, R_OK) == 0) {
mHealthdConfig->batteryTemperaturePath = path;
} else {
path.clear();
path.appendFormat("%s/%s/batt_temp",
POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryTemperaturePath = path;
}
}
if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
path.clear();
path.appendFormat("%s/%s/technology",
POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mHealthdConfig->batteryTechnologyPath = path;
}
path.clear();
path.appendFormat("%s/%s/technology", POWER_SUPPLY_SYSFS_PATH, name);
if (access(path, R_OK) == 0)
mBatteryTechnologyPath = path;
break;
case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
@ -366,19 +400,19 @@ void BatteryMonitor::init(bool nosvcmgr) {
if (!mChargerNames.size())
KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
if (mBatteryStatusPath.isEmpty())
if (mHealthdConfig->batteryStatusPath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
if (mBatteryHealthPath.isEmpty())
if (mHealthdConfig->batteryHealthPath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
if (mBatteryPresentPath.isEmpty())
if (mHealthdConfig->batteryPresentPath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
if (mBatteryCapacityPath.isEmpty())
if (mHealthdConfig->batteryCapacityPath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
if (mBatteryVoltagePath.isEmpty())
if (mHealthdConfig->batteryVoltagePath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
if (mBatteryTemperaturePath.isEmpty())
if (mHealthdConfig->batteryTemperaturePath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
if (mBatteryTechnologyPath.isEmpty())
if (mHealthdConfig->batteryTechnologyPath.isEmpty())
KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
if (nosvcmgr == false) {

View File

@ -21,6 +21,7 @@
#include <utils/String8.h>
#include <utils/Vector.h>
#include "healthd.h"
#include "BatteryPropertiesRegistrar.h"
namespace android {
@ -38,20 +39,11 @@ class BatteryMonitor {
ANDROID_POWER_SUPPLY_TYPE_BATTERY
};
void init(bool nosvcmgr);
void init(struct healthd_config *hc, bool nosvcmgr);
bool update(void);
private:
String8 mBatteryStatusPath;
String8 mBatteryHealthPath;
String8 mBatteryPresentPath;
String8 mBatteryCapacityPath;
String8 mBatteryVoltagePath;
String8 mBatteryTemperaturePath;
String8 mBatteryTechnologyPath;
String8 mBatteryCurrentNowPath;
String8 mBatteryChargeCounterPath;
struct healthd_config *mHealthdConfig;
Vector<String8> mChargerNames;
sp<BatteryPropertiesRegistrar> mBatteryPropertiesRegistrar;

View File

@ -41,6 +41,15 @@ using namespace android;
static struct healthd_config healthd_config = {
.periodic_chores_interval_fast = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST,
.periodic_chores_interval_slow = DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW,
.batteryStatusPath = String8(String8::kEmptyString),
.batteryHealthPath = String8(String8::kEmptyString),
.batteryPresentPath = String8(String8::kEmptyString),
.batteryCapacityPath = String8(String8::kEmptyString),
.batteryVoltagePath = String8(String8::kEmptyString),
.batteryTemperaturePath = String8(String8::kEmptyString),
.batteryTechnologyPath = String8(String8::kEmptyString),
.batteryCurrentNowPath = String8(String8::kEmptyString),
.batteryChargeCounterPath = String8(String8::kEmptyString),
};
#define POWER_SUPPLY_SUBSYSTEM "power_supply"
@ -266,7 +275,7 @@ int main(int argc, char **argv) {
uevent_init();
binder_init();
gBatteryMonitor = new BatteryMonitor();
gBatteryMonitor->init(nosvcmgr);
gBatteryMonitor->init(&healthd_config, nosvcmgr);
healthd_mainloop();
return 0;

View File

@ -18,6 +18,7 @@
#define _HEALTHD_H_
#include <batteryservice/BatteryService.h>
#include <utils/String8.h>
// periodic_chores_interval_fast, periodic_chores_interval_slow: intervals at
// which healthd wakes up to poll health state and perform periodic chores,
@ -32,18 +33,45 @@
// not connected to a charger (to watch for a battery drained to zero
// remaining capacity). The default value is 600 (10 minutes). Value -1
// tuns off periodic chores (and wakeups) in these conditions.
//
// power_supply sysfs attribute file paths. Set these to specific paths
// to use for the associated battery parameters. healthd will search for
// appropriate power_supply attribute files to use for any paths left empty:
//
// batteryStatusPath: charging status (POWER_SUPPLY_PROP_STATUS)
// batteryHealthPath: battery health (POWER_SUPPLY_PROP_HEALTH)
// batteryPresentPath: battery present (POWER_SUPPLY_PROP_PRESENT)
// batteryCapacityPath: remaining capacity (POWER_SUPPLY_PROP_CAPACITY)
// batteryVoltagePath: battery voltage (POWER_SUPPLY_PROP_VOLTAGE_NOW)
// batteryTemperaturePath: battery temperature (POWER_SUPPLY_PROP_TEMP)
// batteryTechnologyPath: battery technology (POWER_SUPPLY_PROP_TECHNOLOGY)
// batteryCurrentNowPath: battery current (POWER_SUPPLY_PROP_CURRENT_NOW)
// batteryChargeCounterPath: battery accumulated charge
// (POWER_SUPPLY_PROP_CHARGE_COUNTER)
struct healthd_config {
int periodic_chores_interval_fast;
int periodic_chores_interval_slow;
android::String8 batteryStatusPath;
android::String8 batteryHealthPath;
android::String8 batteryPresentPath;
android::String8 batteryCapacityPath;
android::String8 batteryVoltagePath;
android::String8 batteryTemperaturePath;
android::String8 batteryTechnologyPath;
android::String8 batteryCurrentNowPath;
android::String8 batteryChargeCounterPath;
};
// The following are implemented in libhealthd_board to handle board-specific
// behavior.
//
//
// To use the default values, this function can simply return without
// modifying the parameters.
// healthd_board_init() is called at startup time to modify healthd's
// configuration according to board-specific requirements. config
// points to the healthd configuration values described above. To use default
// values, this function can simply return without modifying the fields of the
// config parameter.
void healthd_board_init(struct healthd_config *config);