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
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 74fb6a8..688c7ff 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -181,33 +181,33 @@
     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 @@
                  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 @@
             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 @@
                 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;
                 }
 
-                path.clear();
-                path.appendFormat("%s/%s/technology", POWER_SUPPLY_SYSFS_PATH, name);
-                if (access(path, R_OK) == 0)
-                    mBatteryTechnologyPath = 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;
+                }
+
                 break;
 
             case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
@@ -366,19 +400,19 @@
 
     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) {
diff --git a/healthd/BatteryMonitor.h b/healthd/BatteryMonitor.h
index ff1ea1e..ba291af 100644
--- a/healthd/BatteryMonitor.h
+++ b/healthd/BatteryMonitor.h
@@ -21,6 +21,7 @@
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
+#include "healthd.h"
 #include "BatteryPropertiesRegistrar.h"
 
 namespace android {
@@ -38,20 +39,11 @@
         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;
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index 158274c..1719c22 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -41,6 +41,15 @@
 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 @@
     uevent_init();
     binder_init();
     gBatteryMonitor = new BatteryMonitor();
-    gBatteryMonitor->init(nosvcmgr);
+    gBatteryMonitor->init(&healthd_config, nosvcmgr);
 
     healthd_mainloop();
     return 0;
diff --git a/healthd/healthd.h b/healthd/healthd.h
index 895be40..5374fb1 100644
--- a/healthd/healthd.h
+++ b/healthd/healthd.h
@@ -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);