healthd: add health HAL support

Adds board-specific battery monitoring capabilities:

* processing of battery property values and additional charging logic.
* adjusted (or removed) polling intervals.
* replaced (or removed) battery status heartbeat in kernel log.

Change-Id: Ia77bca8dc92c6c2a51afa65d516cacca08da73ac
diff --git a/healthd/Android.mk b/healthd/Android.mk
index 910afb2..cff7a3b 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -18,6 +18,12 @@
 
 LOCAL_STATIC_LIBRARIES :=  libbatteryservice libbinder libz libutils libstdc++ libcutils liblog libm libc
 
+ifdef BOARD_LIB_HEALTHD
+LOCAL_STATIC_LIBRARIES += $(BOARD_LIB_HEALTHD)
+else
+LOCAL_SRC_FILES += healthd_board_default.cpp
+endif
+
 include $(BUILD_EXECUTABLE)
 
 endif
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 882d514..8492dce 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "healthd"
 
+#include "healthd.h"
 #include "BatteryMonitor.h"
 #include "BatteryPropertiesRegistrar.h"
 
@@ -170,6 +171,7 @@
 
 bool BatteryMonitor::update(void) {
     struct BatteryProperties props;
+    bool logthis;
 
     props.chargerAcOnline = false;
     props.chargerUsbOnline = false;
@@ -238,27 +240,31 @@
         }
     }
 
-    char dmesgline[256];
-    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);
+    logthis = !healthd_board_battery_update(&props);
 
-    if (!mBatteryCurrentNowPath.isEmpty()) {
-        char b[20];
+    if (logthis) {
+        char dmesgline[256];
+        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);
 
-        snprintf(b, sizeof(b), " c=%d", props.batteryCurrentNow);
-        strlcat(dmesgline, b, sizeof(dmesgline));
+        if (!mBatteryCurrentNowPath.isEmpty()) {
+            char b[20];
+
+            snprintf(b, sizeof(b), " c=%d", props.batteryCurrentNow);
+            strlcat(dmesgline, b, sizeof(dmesgline));
+        }
+
+        KLOG_INFO(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
+                  props.chargerAcOnline ? "a" : "",
+                  props.chargerUsbOnline ? "u" : "",
+                  props.chargerWirelessOnline ? "w" : "");
     }
 
-    KLOG_INFO(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
-              props.chargerAcOnline ? "a" : "",
-              props.chargerUsbOnline ? "u" : "",
-              props.chargerWirelessOnline ? "w" : "");
-
     if (mBatteryPropertiesRegistrar != NULL)
         mBatteryPropertiesRegistrar->notifyListeners(props);
 
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index 1d79097..89178fa 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "healthd"
 #define KLOG_LEVEL 6
 
+#include "healthd.h"
 #include "BatteryMonitor.h"
 
 #include <errno.h>
@@ -34,8 +35,12 @@
 using namespace android;
 
 // Periodic chores intervals in seconds
-#define PERIODIC_CHORES_INTERVAL_FAST (60 * 1)
-#define PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
+#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)
+#define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
+static int periodic_chores_interval_fast =
+        DEFAULT_PERIODIC_CHORES_INTERVAL_FAST;
+static int periodic_chores_interval_slow =
+        DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW;
 
 #define POWER_SUPPLY_SUBSYSTEM "power_supply"
 
@@ -48,7 +53,7 @@
 // -1 for no epoll timeout
 static int awake_poll_interval = -1;
 
-static int wakealarm_wake_interval = PERIODIC_CHORES_INTERVAL_FAST;
+static int wakealarm_wake_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST;
 
 static BatteryMonitor* gBatteryMonitor;
 
@@ -61,6 +66,10 @@
             return;
 
     wakealarm_wake_interval = interval;
+
+    if (interval == -1)
+        interval = 0;
+
     itval.it_interval.tv_sec = interval;
     itval.it_interval.tv_nsec = 0;
     itval.it_value.tv_sec = interval;
@@ -75,7 +84,7 @@
     // slow wake interval when on battery (watch for drained battery).
 
    int new_wake_interval = gBatteryMonitor->update() ?
-        PERIODIC_CHORES_INTERVAL_FAST : PERIODIC_CHORES_INTERVAL_SLOW;
+        periodic_chores_interval_fast : periodic_chores_interval_slow;
 
     if (new_wake_interval != wakealarm_wake_interval)
             wakealarm_set_interval(new_wake_interval);
@@ -85,9 +94,12 @@
     // poll at fast rate while awake and let alarm wake up at slow rate when
     // asleep.
 
-    awake_poll_interval =
-        new_wake_interval == PERIODIC_CHORES_INTERVAL_FAST ?
-        -1 : PERIODIC_CHORES_INTERVAL_FAST * 1000;
+    if (periodic_chores_interval_fast == -1)
+        awake_poll_interval = -1;
+    else
+        awake_poll_interval =
+            new_wake_interval == periodic_chores_interval_fast ?
+                -1 : periodic_chores_interval_fast * 1000;
 }
 
 static void periodic_chores() {
@@ -138,7 +150,10 @@
         return;
     }
 
-    wakealarm_set_interval(PERIODIC_CHORES_INTERVAL_FAST);
+    healthd_board_poll_intervals(&periodic_chores_interval_fast,
+                                 &periodic_chores_interval_slow);
+
+    wakealarm_set_interval(periodic_chores_interval_fast);
 }
 
 static void wakealarm_event(void) {
diff --git a/healthd/healthd.h b/healthd/healthd.h
new file mode 100644
index 0000000..18ad03a
--- /dev/null
+++ b/healthd/healthd.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HEALTHD_H_
+#define _HEALTHD_H_
+
+#include <batteryservice/BatteryService.h>
+
+// The following are implemented in libhealthd_board to handle board-specific
+// behavior.
+//
+// Set periodic poll intervals in seconds.
+//
+// fast_interval is used while the device is not in suspend, or in suspend and
+// connected to a charger (to watch for battery overheat due to charging).
+// The default value is 60 (1 minute).  Value -1 turns off fast_interval
+// polling.
+//
+// slow_interval is used when the device is in suspend and 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 slow interval
+// polling.
+//
+// To use the default values, this function can simply return without
+// modifying the parameters.
+
+void healthd_board_poll_intervals(int *fast_interval, int *slow_interval);
+
+// Process updated battery property values.  This function is called when
+// the kernel sends updated battery status via a uevent from the power_supply
+// subsystem, or when updated values are polled by healthd, as for periodic
+// poll of battery state.
+//
+// props are the battery properties read from the kernel.  These values may
+// be modified in this call, prior to sending the modified values to the
+// Android runtime.
+//
+// Return 0 to indicate the usual kernel log battery status heartbeat message
+// is to be logged, or non-zero to prevent logging this information.
+
+int healthd_board_battery_update(struct android::BatteryProperties *props);
+
+#endif /* _HEALTHD_H_ */
diff --git a/healthd/healthd_board_default.cpp b/healthd/healthd_board_default.cpp
new file mode 100644
index 0000000..82f37fe
--- /dev/null
+++ b/healthd/healthd_board_default.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <healthd.h>
+
+void healthd_board_poll_intervals(int *fast_interval, int *slow_interval)
+{
+    // use defaults
+}
+
+
+int healthd_board_battery_update(struct android::BatteryProperties *props)
+{
+    // return 0 to log periodic polled battery status to kernel log
+    return 0;
+}