BatteryMonitor.cpp revision d5fe6675a73c3a831d0c4e41343ee86772633db8
1752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor/* 2752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * Copyright (C) 2013 The Android Open Source Project 3752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * 4752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * Licensed under the Apache License, Version 2.0 (the "License"); 5752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * you may not use this file except in compliance with the License. 6752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * You may obtain a copy of the License at 7752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * 8752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * http://www.apache.org/licenses/LICENSE-2.0 9752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * 10752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * Unless required by applicable law or agreed to in writing, software 11752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * distributed under the License is distributed on an "AS IS" BASIS, 12752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * See the License for the specific language governing permissions and 14752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor * limitations under the License. 15752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor */ 16752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 17752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define LOG_TAG "healthd" 18752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 1910b235e7436256da9adc827125645f141bd8fac9Todd Poynor#include "healthd.h" 20752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include "BatteryMonitor.h" 21752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 22752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <dirent.h> 23752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <errno.h> 24752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <fcntl.h> 25752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <stdio.h> 26752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <stdlib.h> 27752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <unistd.h> 28752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <batteryservice/BatteryService.h> 29752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <cutils/klog.h> 303db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor#include <cutils/properties.h> 31e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor#include <sys/types.h> 32c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor#include <utils/Errors.h> 33752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/String8.h> 34752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/Vector.h> 35752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 36752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SUBSYSTEM "power_supply" 37752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM 38a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi#define FAKE_BATTERY_CAPACITY 42 39a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi#define FAKE_BATTERY_TEMPERATURE 424 40752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 41752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynornamespace android { 42752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 43752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstruct sysfsStringEnumMap { 446f5b47f9144960412b0fb6bc417f0c41bf53438aMark Salyzyn const char* s; 45752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int val; 46752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}; 47752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 48752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstatic int mapSysfsString(const char* str, 49752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap map[]) { 50752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor for (int i = 0; map[i].s; i++) 51752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (!strcmp(str, map[i].s)) 52752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return map[i].val; 53752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 54752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return -1; 55752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 56752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 57752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryStatus(const char* status) { 58752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int ret; 59752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap batteryStatusMap[] = { 60752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unknown", BATTERY_STATUS_UNKNOWN }, 61752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Charging", BATTERY_STATUS_CHARGING }, 62752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Discharging", BATTERY_STATUS_DISCHARGING }, 63752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Not charging", BATTERY_STATUS_NOT_CHARGING }, 64752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Full", BATTERY_STATUS_FULL }, 65752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { NULL, 0 }, 66752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor }; 67752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 68752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = mapSysfsString(status, batteryStatusMap); 69752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (ret < 0) { 70752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status); 71752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = BATTERY_STATUS_UNKNOWN; 72752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 73752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 74752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ret; 75752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 76752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 77752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryHealth(const char* status) { 78752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int ret; 79752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap batteryHealthMap[] = { 80752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unknown", BATTERY_HEALTH_UNKNOWN }, 81752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Good", BATTERY_HEALTH_GOOD }, 82752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Overheat", BATTERY_HEALTH_OVERHEAT }, 83752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Dead", BATTERY_HEALTH_DEAD }, 84752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE }, 85752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE }, 86752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Cold", BATTERY_HEALTH_COLD }, 87752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { NULL, 0 }, 88752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor }; 89752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 90752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = mapSysfsString(status, batteryHealthMap); 91752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (ret < 0) { 92752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status); 93752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = BATTERY_HEALTH_UNKNOWN; 94752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 95752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 96752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ret; 97752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 98752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 99752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::readFromFile(const String8& path, char* buf, size_t size) { 100752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char *cp = NULL; 101752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 102752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (path.isEmpty()) 103752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return -1; 104752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int fd = open(path.string(), O_RDONLY, 0); 105752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (fd == -1) { 106752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_ERROR(LOG_TAG, "Could not open '%s'\n", path.string()); 107752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return -1; 108752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 109752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 110752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ssize_t count = TEMP_FAILURE_RETRY(read(fd, buf, size)); 111752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (count > 0) 112752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor cp = (char *)memrchr(buf, '\n', count); 113752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 114752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (cp) 115752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor *cp = '\0'; 116752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor else 117752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor buf[0] = '\0'; 118752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 119752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor close(fd); 120752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return count; 121752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 122752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 123752faf2c18407fd79127fb3f3773910b4ddf669dTodd PoynorBatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) { 124752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 128; 125752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 126752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int length = readFromFile(path, buf, SIZE); 127752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor BatteryMonitor::PowerSupplyType ret; 128752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap supplyTypeMap[] = { 129752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN }, 130752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY }, 131752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "UPS", ANDROID_POWER_SUPPLY_TYPE_AC }, 132752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Mains", ANDROID_POWER_SUPPLY_TYPE_AC }, 133752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB", ANDROID_POWER_SUPPLY_TYPE_USB }, 134752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC }, 135752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC }, 136752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC }, 137752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS }, 138752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { NULL, 0 }, 139752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor }; 140752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 141752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (length <= 0) 142752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; 143752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 144752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = (BatteryMonitor::PowerSupplyType)mapSysfsString(buf, supplyTypeMap); 145752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (ret < 0) 146752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; 147752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 148752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ret; 149752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 150752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 151752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::getBooleanField(const String8& path) { 152752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 16; 153752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 154752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 155752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor bool value = false; 156752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (readFromFile(path, buf, SIZE) > 0) { 157752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (buf[0] != '0') { 158752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor value = true; 159752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 160752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 161752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 162752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return value; 163752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 164752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 165752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getIntField(const String8& path) { 166752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 128; 167752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 168752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 169752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int value = 0; 170752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (readFromFile(path, buf, SIZE) > 0) { 171752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor value = strtol(buf, NULL, 0); 172752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 173752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return value; 174752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 175752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 176752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::update(void) { 17710b235e7436256da9adc827125645f141bd8fac9Todd Poynor bool logthis; 178752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 179752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerAcOnline = false; 180752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerUsbOnline = false; 181752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerWirelessOnline = false; 182752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryStatus = BATTERY_STATUS_UNKNOWN; 183752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryHealth = BATTERY_HEALTH_UNKNOWN; 184d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos props.maxChargingCurrent = 0; 185752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 186f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (!mHealthdConfig->batteryPresentPath.isEmpty()) 187f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); 188752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor else 1896dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor props.batteryPresent = mBatteryDevicePresent; 190752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 1913db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor props.batteryLevel = mBatteryFixedCapacity ? 1923db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor mBatteryFixedCapacity : 1933db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor getIntField(mHealthdConfig->batteryCapacityPath); 194f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000; 195b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 1963db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor props.batteryTemperature = mBatteryFixedTemperature ? 1973db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor mBatteryFixedTemperature : 1983db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor getIntField(mHealthdConfig->batteryTemperaturePath); 199752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 200752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 128; 201752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 202752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor String8 btech; 203752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 204f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0) 205752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryStatus = getBatteryStatus(buf); 206752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 207f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0) 208752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryHealth = getBatteryHealth(buf); 209752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 210f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0) 211752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryTechnology = String8(buf); 212752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 213752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor unsigned int i; 214752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 215752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor for (i = 0; i < mChargerNames.size(); i++) { 216752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor String8 path; 217752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, 218752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames[i].string()); 219752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 220752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (readFromFile(path, buf, SIZE) > 0) { 221752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (buf[0] != '0') { 222752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 223752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, 224752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames[i].string()); 225752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor switch(readPowerSupplyType(path)) { 226752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_AC: 227752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerAcOnline = true; 228752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 229752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_USB: 230752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerUsbOnline = true; 231752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 232752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: 233752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerWirelessOnline = true; 234752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 235752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor default: 236752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", 237752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames[i].string()); 238752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 239d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos path.clear(); 240d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, 241d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos mChargerNames[i].string()); 242d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos if (access(path.string(), R_OK) == 0) { 243d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos int maxChargingCurrent = getIntField(path); 244d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos if (props.maxChargingCurrent < maxChargingCurrent) { 245d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos props.maxChargingCurrent = maxChargingCurrent; 246d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos } 247d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos } 248752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 249752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 250752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 251752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 25210b235e7436256da9adc827125645f141bd8fac9Todd Poynor logthis = !healthd_board_battery_update(&props); 253b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 25410b235e7436256da9adc827125645f141bd8fac9Todd Poynor if (logthis) { 25510b235e7436256da9adc827125645f141bd8fac9Todd Poynor char dmesgline[256]; 2566dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor 257c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor if (props.batteryPresent) { 2586dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor snprintf(dmesgline, sizeof(dmesgline), 25910b235e7436256da9adc827125645f141bd8fac9Todd Poynor "battery l=%d v=%d t=%s%d.%d h=%d st=%d", 26010b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.batteryLevel, props.batteryVoltage, 26110b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.batteryTemperature < 0 ? "-" : "", 26210b235e7436256da9adc827125645f141bd8fac9Todd Poynor abs(props.batteryTemperature / 10), 26310b235e7436256da9adc827125645f141bd8fac9Todd Poynor abs(props.batteryTemperature % 10), props.batteryHealth, 26410b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.batteryStatus); 265b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 266c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 267c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor int c = getIntField(mHealthdConfig->batteryCurrentNowPath); 268c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor char b[20]; 26910b235e7436256da9adc827125645f141bd8fac9Todd Poynor 270c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor snprintf(b, sizeof(b), " c=%d", c / 1000); 271c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor strlcat(dmesgline, b, sizeof(dmesgline)); 272c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor } 273c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor } else { 274c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor snprintf(dmesgline, sizeof(dmesgline), 275c15e9934675d2f6b8dc19f042e6d045415e79359Todd Poynor "battery none"); 27610b235e7436256da9adc827125645f141bd8fac9Todd Poynor } 277b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 278ebeb0c0ea63af9fd8b2c8a7a20f919e48098ad9aTodd Poynor KLOG_WARNING(LOG_TAG, "%s chg=%s%s%s\n", dmesgline, 279ebeb0c0ea63af9fd8b2c8a7a20f919e48098ad9aTodd Poynor props.chargerAcOnline ? "a" : "", 280ebeb0c0ea63af9fd8b2c8a7a20f919e48098ad9aTodd Poynor props.chargerUsbOnline ? "u" : "", 281ebeb0c0ea63af9fd8b2c8a7a20f919e48098ad9aTodd Poynor props.chargerWirelessOnline ? "w" : ""); 28210b235e7436256da9adc827125645f141bd8fac9Todd Poynor } 283752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 284c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynor healthd_mode_ops->battery_update(&props); 285752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return props.chargerAcOnline | props.chargerUsbOnline | 286752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerWirelessOnline; 287752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 288752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 289c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynorstatus_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { 290c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor status_t ret = BAD_VALUE; 291c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 2928f132af495d208272ea55d0ca24068926fa80e51Todd Poynor val->valueInt64 = LONG_MIN; 2938f132af495d208272ea55d0ca24068926fa80e51Todd Poynor 294c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor switch(id) { 295c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor case BATTERY_PROP_CHARGE_COUNTER: 296c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) { 2978f132af495d208272ea55d0ca24068926fa80e51Todd Poynor val->valueInt64 = 298c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor getIntField(mHealthdConfig->batteryChargeCounterPath); 299c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NO_ERROR; 300c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } else { 301c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NAME_NOT_FOUND; 302c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } 303c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor break; 304c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 305c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor case BATTERY_PROP_CURRENT_NOW: 306c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 3078f132af495d208272ea55d0ca24068926fa80e51Todd Poynor val->valueInt64 = 308c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor getIntField(mHealthdConfig->batteryCurrentNowPath); 309c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NO_ERROR; 310c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } else { 311c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NAME_NOT_FOUND; 312c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } 313c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor break; 314c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 315bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor case BATTERY_PROP_CURRENT_AVG: 316bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) { 3178f132af495d208272ea55d0ca24068926fa80e51Todd Poynor val->valueInt64 = 318bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor getIntField(mHealthdConfig->batteryCurrentAvgPath); 319bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor ret = NO_ERROR; 320bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor } else { 321bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor ret = NAME_NOT_FOUND; 322bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor } 323bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor break; 324bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor 325347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence case BATTERY_PROP_CAPACITY: 326347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence if (!mHealthdConfig->batteryCapacityPath.isEmpty()) { 3278f132af495d208272ea55d0ca24068926fa80e51Todd Poynor val->valueInt64 = 328347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence getIntField(mHealthdConfig->batteryCapacityPath); 329347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence ret = NO_ERROR; 330347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence } else { 331347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence ret = NAME_NOT_FOUND; 332347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence } 333347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence break; 334347c8de285454af2d3cba3d9b43d3bf23b20babbPaul Lawrence 3358f132af495d208272ea55d0ca24068926fa80e51Todd Poynor case BATTERY_PROP_ENERGY_COUNTER: 336e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor if (mHealthdConfig->energyCounter) { 337e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor ret = mHealthdConfig->energyCounter(&val->valueInt64); 338e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor } else { 339e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor ret = NAME_NOT_FOUND; 340e14b37eb07b394fef05da5ee09dc6d33e3a25711Todd Poynor } 3418f132af495d208272ea55d0ca24068926fa80e51Todd Poynor break; 3428f132af495d208272ea55d0ca24068926fa80e51Todd Poynor 343c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor default: 344c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor break; 345c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } 346c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 347c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor return ret; 348c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor} 349c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 350020369d8724eff2b87350e54e157a609846166e4Todd Poynorvoid BatteryMonitor::dumpState(int fd) { 351020369d8724eff2b87350e54e157a609846166e4Todd Poynor int v; 352020369d8724eff2b87350e54e157a609846166e4Todd Poynor char vs[128]; 353020369d8724eff2b87350e54e157a609846166e4Todd Poynor 354d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d\n", 355020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.chargerAcOnline, props.chargerUsbOnline, 356d5fe6675a73c3a831d0c4e41343ee86772633db8Adrian Roos props.chargerWirelessOnline, props.maxChargingCurrent); 357020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 358020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", 359020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.batteryStatus, props.batteryHealth, props.batteryPresent); 360020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 361020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", 362020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.batteryLevel, props.batteryVoltage, 363020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.batteryTemperature); 364020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 365020369d8724eff2b87350e54e157a609846166e4Todd Poynor 366020369d8724eff2b87350e54e157a609846166e4Todd Poynor if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 367020369d8724eff2b87350e54e157a609846166e4Todd Poynor v = getIntField(mHealthdConfig->batteryCurrentNowPath); 368020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "current now: %d\n", v); 369020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 370020369d8724eff2b87350e54e157a609846166e4Todd Poynor } 371020369d8724eff2b87350e54e157a609846166e4Todd Poynor 372020369d8724eff2b87350e54e157a609846166e4Todd Poynor if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) { 373020369d8724eff2b87350e54e157a609846166e4Todd Poynor v = getIntField(mHealthdConfig->batteryCurrentAvgPath); 374020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "current avg: %d\n", v); 375020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 376020369d8724eff2b87350e54e157a609846166e4Todd Poynor } 377020369d8724eff2b87350e54e157a609846166e4Todd Poynor 378020369d8724eff2b87350e54e157a609846166e4Todd Poynor if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) { 379020369d8724eff2b87350e54e157a609846166e4Todd Poynor v = getIntField(mHealthdConfig->batteryChargeCounterPath); 380020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "charge counter: %d\n", v); 381020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 382020369d8724eff2b87350e54e157a609846166e4Todd Poynor } 383020369d8724eff2b87350e54e157a609846166e4Todd Poynor} 384020369d8724eff2b87350e54e157a609846166e4Todd Poynor 385c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynorvoid BatteryMonitor::init(struct healthd_config *hc) { 386752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor String8 path; 3873db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor char pval[PROPERTY_VALUE_MAX]; 388752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 389f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig = hc; 390752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH); 391752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (dir == NULL) { 392752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH); 393752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } else { 394752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct dirent* entry; 395752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 396752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor while ((entry = readdir(dir))) { 397752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const char* name = entry->d_name; 398752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 399752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (!strcmp(name, ".") || !strcmp(name, "..")) 400752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor continue; 401752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 402752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor // Look for "type" file in each subdirectory 403752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 404752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name); 405752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor switch(readPowerSupplyType(path)) { 406752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_AC: 407752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_USB: 408752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: 409752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 410752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name); 411752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (access(path.string(), R_OK) == 0) 412752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames.add(String8(name)); 413752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 414752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 415752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_BATTERY: 4166dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor mBatteryDevicePresent = true; 4176dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor 418f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryStatusPath.isEmpty()) { 419f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 420f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH, 421f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 422f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 423f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryStatusPath = path; 424f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 425752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 426f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryHealthPath.isEmpty()) { 427752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 428f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH, 429f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 430752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (access(path, R_OK) == 0) 431f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryHealthPath = path; 432752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 433752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 434f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryPresentPath.isEmpty()) { 435f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 436f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH, 437f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 438f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 439f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryPresentPath = path; 440f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 441b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 442f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryCapacityPath.isEmpty()) { 443f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 444f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH, 445f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 446f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 447f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryCapacityPath = path; 448f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 449b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 450f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryVoltagePath.isEmpty()) { 451f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 452f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/voltage_now", 453f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 454f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) { 455f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryVoltagePath = path; 456f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } else { 457f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 458f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/batt_vol", 459f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 460f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 461f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryVoltagePath = path; 462f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 463f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 464f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 465f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 466752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 467f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/current_now", 468f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 469752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (access(path, R_OK) == 0) 470f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryCurrentNowPath = path; 471f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 472f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 473bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) { 474bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor path.clear(); 475bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor path.appendFormat("%s/%s/current_avg", 476bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 477bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor if (access(path, R_OK) == 0) 478bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor mHealthdConfig->batteryCurrentAvgPath = path; 479bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor } 480bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor 481f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) { 482f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 483f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/charge_counter", 484f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 485f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 486f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryChargeCounterPath = path; 487f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 488f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 489f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryTemperaturePath.isEmpty()) { 490f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 491f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH, 492f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 493f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) { 494f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryTemperaturePath = path; 495f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } else { 496f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 497f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/batt_temp", 498f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 499f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 500f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryTemperaturePath = path; 501f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 502f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 503f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 504f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryTechnologyPath.isEmpty()) { 505f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 506f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/technology", 507f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 508f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 509f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryTechnologyPath = path; 510752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 511752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 512752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 513752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 514752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN: 515752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 516752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 517752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 518752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor closedir(dir); 519752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 520752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 521752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (!mChargerNames.size()) 522752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_ERROR(LOG_TAG, "No charger supplies found\n"); 5236dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (!mBatteryDevicePresent) { 524ebeb0c0ea63af9fd8b2c8a7a20f919e48098ad9aTodd Poynor KLOG_WARNING(LOG_TAG, "No battery devices found\n"); 5256dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor hc->periodic_chores_interval_fast = -1; 5266dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor hc->periodic_chores_interval_slow = -1; 5276dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor } else { 5286dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryStatusPath.isEmpty()) 5296dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n"); 5306dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryHealthPath.isEmpty()) 5316dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n"); 5326dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryPresentPath.isEmpty()) 5336dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n"); 5346dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryCapacityPath.isEmpty()) 5356dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n"); 5366dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryVoltagePath.isEmpty()) 5376dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n"); 5386dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryTemperaturePath.isEmpty()) 5396dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n"); 5406dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryTechnologyPath.isEmpty()) 5416dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n"); 5426dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor } 5433db03a5ab0cb7713529c298531be6da7c2193525Todd Poynor 544a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi if (property_get("ro.boot.fake_battery", pval, NULL) > 0 545a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi && strtol(pval, NULL, 10) != 0) { 546a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY; 547a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE; 548a78fc23491f3490bec4e4ac72c4bdc8c6d554fe3Ruchi Kandoi } 549752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 550752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 551752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}; // namespace android 552