[Samsung Galaxy Nexus] freshgiammi:
What if i told you.. i tried that ~2/3 weeks ago resulting in a "lolnope"?

/*
* 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.
*/
#define LOG_TAG "healthd-tuna"
#include <errno.h>
#include <fcntl.h>
#include <healthd.h>
#include <time.h>
#include <unistd.h>
#include <batteryservice/BatteryService.h>
#include <cutils/klog.h>
#include <sys/stat.h>
#include <sys/types.h>

#define POWER_SUPPLY_SUBSYSTEM "power_supply"
#define POWER_SUPPLY_SYSFS_PATH "/sys/class" POWER_SUPPLY_SUBSYSTEM

#define MAX17040_PATH "/max17040-battery"

using namespace android;

#define TEMP_HIGH_THRESHOLD 650 /* 65C */
#define TEMP_HIGH_RECOVERY 450 /* 45C */
#define TEMP_LOW_RECOVERY 0 /* 0C */
#define TEMP_LOW_THRESHOLD -50 /* -5C */

#define FULL_CHARGING_TIME (12 * 60 * 60)
#define RECHARGING_TIME (2 * 60 * 60)
#define RECHARGING_VOLTAGE (4250)

static bool tuna_bat_recharging;
static time_t tuna_bat_recharging_start_time;

static unsigned int tuna_bat_health = BATTERY_HEALTH_GOOD;
static unsigned int tuna_bat_charging_status = BATTERY_STATUS_DISCHARGING;
static boot tuna_bat_batterypresent;

static ing charge_enabled_fd;

static void tuna_bat_check_temp(struct BatteryProperties *props)
{
if (props->chargerAcOnline == false &&
props->chargerUsbOnline == false)
return;

if (props->batteryTemperature >= TEMP_HIGH_THRESHOLD) {
if (tuna_bat_health != BATTERY_HEALTH_OVERHEAT &&
tuna_bat_health != BATTERY_HEALTH_UNSPECIFIED_FAILURE) {
KLOG_INFO(LOG_TAG,
"battery overheat (%d), charging unavailable\n",
props->batteryTemperature);
tuna_bat_health = BATTERY_HEALTH_OVERHEAT;
}
} else if (props->batteryTemperature <= TEMP_HIGH_RECOVERY &&
props->batteryTemperature >= TEMP_LOW_RECOVERY) {
if (tuna_bat_health == BATTERY_HEALTH_OVERHEAT ||
tuna_bat_health == BATTERY_HEALTH_COLD) {
KLOG_INFO(LOG_TAG,
"battery recovery (%d), charging available\n",
props->batteryTemperature);
tuna_bat_health = BATTERY_HEALTH_GOOD;
}
} else if (props->batteryTemperature <= TEMP_LOW_THRESHOLD) {
if (tuna_bat_health != BATTERY_HEALTH_COLD &&
tuna_bat_health != BATTERY_HEALTH_UNSPECIFIED_FAILURE) {
KLOG_INFO(LOG_TAG,
"battery cold (%d), charging unavailable\n",
props->batteryTemperature);
tuna_bat_health = BATTERY_HEALTH_COLD;
}
}
}

static void tuna_bat_set_charge_time(bool enable)
{
if (enable && !tuna_bat_charging_start_time)
time(&tuna_bat_charging_start_time);
else if (!enable)
tuna_bat_charging_start_time = 0;
}

static void tuna_bat_enable_charging(bool enable)
{
int ret;
char val[20];

if (enable && (tuna_bat_health != BATTERY_HEALTH_GOOD)) {
tuna_bat_charging_status = BATTERY_STATUS_NOT_CHARGING;
return;
}

if (charge_enabled_fd < 0)
goto err;

snprintf(val, sizeof(val), "%d", enable);
ret = write(charge_enabled_fd, val, strlen(val));
if (ret == -1) {
KLOG_ERROR(LOG_TAG, "charge_enabled write error; errno=%d\n", errno);
goto err;
}

tuna_bat_set_charge_time(enable);
KLOG_INFO(LOG_TAG, "battery charge enable=%d\n", enable);
return;

err:
if (enable)
tuna_bat_charging_status = BATTERY_STATUS_NOT_CHARGING;
}

static bool tuna_bat_charge_timeout(time_t timeout)
{
if (!tuna_bat_charging_start_time)
return false;

return time(NULL) >= tuna_bat_charging_start_time + timeout;
}

static void tuna_bat_set_full(void)
{
KLOG_INFO(LOG_TAG, "battery full\n");
tuna_bat_charging_status = BATTERY_STATUS_FULL;
tuna_bat_enable_charging(false);
tuna_bat_recharging = false;
}

static void tuna_bat_charging_timer(struct BatteryProperties *props)
{
if (!tuna_bat_charging_start_time &&
tuna_bat_charging_status == BATTERY_STATUS_CHARGING) {
KLOG_WARNING("battery charging timer not started, starting\n");
tuna_bat_enable_charging(true);
tuna_bat_recharging = true;
} else if (!tuna_bat_charging_start_time) {
return;
}

if (tuna_bat_charge_timeout(tuna_bat_recharging ?
RECHARGING_TIME : FULL_CHARGING_TIME)) {
KLOG_INFO(LOG_TAG, "battery charging timer expired\n");
if (props->batteryVoltage > RECHARGING_VOLTAGE &&
props->batteryLevel == 100) {
tuna_bat_set_full();
} else {
tuna_bat_enable_charging(false);
tuna_bat_recharging = false;
tuna_bat_charging_start_time = 0;
}
}
}

static void tuna_bat_check_charge_source_changed(
struct BatteryProperties *props)
{
if (props->chargerUsbOnline || props->chargerAcOnline) {
if (tuna_bat_charging_status == BATTERY_STATUS_CHARGING)
return;

/*
* If charging status indicates a charger was already
* connected prior to this and the status is something
* other than charging ("full" or "not-charging"), leave
* the status alone.
*/
if (tuna_bat_charging_status == BATTERY_STATUS_DISCHARGING ||
tuna_bat_charging_status == BATTERY_STATUS_UNKNOWN)
tuna_bat_charging_status = BATTERY_STATUS_CHARGING;

/*
* Don't re-enable charging if the battery is full and we
* are not actively re-charging it, or if "not-charging"
* status is set.
*/
if (!(tuna_bat_charging_status == BATTERY_STATUS_FULL
&& !tuna_bat_recharging) &&
tuna_bat_charging_status != BATTERY_STATUS_NOT_CHARGING)
tuna_bat_enable_charging(true);
} else if (tuna_bat_charging_status == BATTERY_STATUS_CHARGING ||
tuna_bat_charging_status == BATTERY_STATUS_NOT_CHARGING ||
tuna_bat_charging_status == BATTERY_STATUS_FULL) {
tuna_bat_charging_status = BATTERY_STATUS_DISCHARGING;
tuna_bat_enable_charging(false);
tuna_bat_health = BATTERY_HEALTH_GOOD;
tuna_bat_recharging = false;
tuna_bat_charging_start_time = 0;
}
}

static void tuna_bat_monitor(struct BatteryProperties *props)
{
unsigned int old_bat_health = tuna_bat_health;

if (tuna_bat_batterypresent) {
tuna_bat_check_temp(props);
} else {
props->batteryTemperature = 42; /* 4.2C */
props->batteryVoltage = 4242; /* 4242mV */
props->batteryLevel = 42; /* 42% */
props->batteryCurrentNow = 42000;/* 42mA */
}

if (props->batteryStatus == BATTERY_STATUS_FULL &&
tuna_bat_charging_status == BATTERY_STATUS_CHARGING &&
!tuna_bat_recharging) {
tuna_bat_set_full();
}

tuna_bat_check_charge_source_changed(props);

switch (tuna_bat_charging_status) {
case BATTERY_STATUS_FULL:
if (props->batteryVoltage < RECHARGING_VOLTAGE &&
!tuna_bat_recharging) {
KLOG_INFO(LOG_TAG, "start recharging, v=%d\n",
props->batteryVoltage);
tuna_bat_recharging = true;
tuna_bat_enable_charging(true);
}
break;
case BATTERY_STATUS_DISCHARGING:
break;
case BATTERY_STATUS_CHARGING:
switch (tuna_bat_health) {
case BATTERY_HEALTH_OVERHEAT:
case BATTERY_HEALTH_COLD:
case BATTERY_HEALTH_OVER_VOLTAGE:
case BATTERY_HEALTH_DEAD:
case BATTERY_HEALTH_UNSPECIFIED_FAILURE:
tuna_bat_charging_status = BATTERY_STATUS_NOT_CHARGING;
tuna_bat_enable_charging(false);
KLOG_INFO(LOG_TAG, "Not charging, health=%d\n",
tuna_bat_health);
break;
default:
break;
}
break;
case BATTERY_STATUS_NOT_CHARGING:
if (old_bat_health != BATTERY_HEALTH_GOOD &&
tuna_bat_health == BATTERY_HEALTH_GOOD) {
KLOG_INFO(LOG_TAG, "battery health recovered\n");

if (props->chargerUsbOnline || props->chargerAcOnline) {
tuna_bat_enable_charging(true);
tuna_bat_charging_status = BATTERY_STATUS_CHARGING;
} else {
tuna_bat_charging_status =
BATTERY_STATUS_DISCHARGING;
}
}
break;
default:
break;
}

tuna_bat_charging_timer(props);

// set health and status according to our state, hardcode invariants
props->batteryHealth = tuna_bat_health;
props->batteryStatus = tuna_bat_charging_status;
props->batteryTechnology = "Li-ion";
props->batteryPresent = tuna_bat_batterypresent;
}

int healthd_board_battery_update(struct BatteryProperties *props)
{
tuna_bat_monitor(props);

// return 0 to log periodic polled battery status to kernel log
return 0;
}

void healthd_board_init(struct healthd_config *config)
{
charge_enabled_fd = open(POWER_SUPPLY_SYSFS_PATH
"/tuna-battery/charge_enabled", O_WRONLY);
if (charge_enabled_fd == -1)
KLOG_ERROR(LOG_TAG, "open tuna-battery/charge_enabled failed"
"; errno=%d\n", errno);

config->batteryCurrentNowPath = MAX17040_PATH "/current_now";

if (access(config->batteryCurrentNowPath.string(), R_OK) == 0) {
tuna_bat_batterypresent = true;
} else {
KLOG_INFO("Missing battery, using fake battery data\n");
config->batteryCurrentNowPath.clear();
}
}

;)

EDIT: I actually garbaged the commit that i used. That's a leftover from a Pastebin that i did, and there are some things that are broken. Mainly the path for MAX17040 and the final stuff.