BatteryMonitor.cpp revision 020369d8724eff2b87350e54e157a609846166e4
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> 30c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor#include <utils/Errors.h> 31752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/String8.h> 32752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#include <utils/Vector.h> 33752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 34752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SUBSYSTEM "power_supply" 35752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM 36752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 37752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynornamespace android { 38752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 39752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstruct sysfsStringEnumMap { 40752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char* s; 41752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int val; 42752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}; 43752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 44752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorstatic int mapSysfsString(const char* str, 45752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap map[]) { 46752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor for (int i = 0; map[i].s; i++) 47752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (!strcmp(str, map[i].s)) 48752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return map[i].val; 49752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 50752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return -1; 51752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 52752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 53752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryStatus(const char* status) { 54752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int ret; 55752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap batteryStatusMap[] = { 56752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unknown", BATTERY_STATUS_UNKNOWN }, 57752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Charging", BATTERY_STATUS_CHARGING }, 58752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Discharging", BATTERY_STATUS_DISCHARGING }, 59752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Not charging", BATTERY_STATUS_NOT_CHARGING }, 60752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Full", BATTERY_STATUS_FULL }, 61752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { NULL, 0 }, 62752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor }; 63752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 64752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = mapSysfsString(status, batteryStatusMap); 65752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (ret < 0) { 66752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status); 67752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = BATTERY_STATUS_UNKNOWN; 68752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 69752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 70752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ret; 71752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 72752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 73752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getBatteryHealth(const char* status) { 74752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int ret; 75752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap batteryHealthMap[] = { 76752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unknown", BATTERY_HEALTH_UNKNOWN }, 77752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Good", BATTERY_HEALTH_GOOD }, 78752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Overheat", BATTERY_HEALTH_OVERHEAT }, 79752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Dead", BATTERY_HEALTH_DEAD }, 80752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE }, 81752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE }, 82752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Cold", BATTERY_HEALTH_COLD }, 83752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { NULL, 0 }, 84752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor }; 85752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 86752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = mapSysfsString(status, batteryHealthMap); 87752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (ret < 0) { 88752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status); 89752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = BATTERY_HEALTH_UNKNOWN; 90752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 91752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 92752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ret; 93752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 94752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 95752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::readFromFile(const String8& path, char* buf, size_t size) { 96752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char *cp = NULL; 97752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 98752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (path.isEmpty()) 99752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return -1; 100752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int fd = open(path.string(), O_RDONLY, 0); 101752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (fd == -1) { 102752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_ERROR(LOG_TAG, "Could not open '%s'\n", path.string()); 103752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return -1; 104752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 105752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 106752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ssize_t count = TEMP_FAILURE_RETRY(read(fd, buf, size)); 107752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (count > 0) 108752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor cp = (char *)memrchr(buf, '\n', count); 109752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 110752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (cp) 111752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor *cp = '\0'; 112752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor else 113752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor buf[0] = '\0'; 114752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 115752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor close(fd); 116752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return count; 117752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 118752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 119752faf2c18407fd79127fb3f3773910b4ddf669dTodd PoynorBatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String8& path) { 120752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 128; 121752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 122752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int length = readFromFile(path, buf, SIZE); 123752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor BatteryMonitor::PowerSupplyType ret; 124752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct sysfsStringEnumMap supplyTypeMap[] = { 125752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN }, 126752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY }, 127752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "UPS", ANDROID_POWER_SUPPLY_TYPE_AC }, 128752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Mains", ANDROID_POWER_SUPPLY_TYPE_AC }, 129752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB", ANDROID_POWER_SUPPLY_TYPE_USB }, 130752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB_DCP", ANDROID_POWER_SUPPLY_TYPE_AC }, 131752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB_CDP", ANDROID_POWER_SUPPLY_TYPE_AC }, 132752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "USB_ACA", ANDROID_POWER_SUPPLY_TYPE_AC }, 133752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS }, 134752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor { NULL, 0 }, 135752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor }; 136752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 137752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (length <= 0) 138752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; 139752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 140752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = (BatteryMonitor::PowerSupplyType)mapSysfsString(buf, supplyTypeMap); 141752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (ret < 0) 142752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; 143752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 144752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return ret; 145752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 146752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 147752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::getBooleanField(const String8& path) { 148752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 16; 149752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 150752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 151752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor bool value = false; 152752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (readFromFile(path, buf, SIZE) > 0) { 153752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (buf[0] != '0') { 154752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor value = true; 155752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 156752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 157752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 158752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return value; 159752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 160752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 161752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorint BatteryMonitor::getIntField(const String8& path) { 162752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 128; 163752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 164752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 165752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor int value = 0; 166752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (readFromFile(path, buf, SIZE) > 0) { 167752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor value = strtol(buf, NULL, 0); 168752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 169752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return value; 170752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 171752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 172752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynorbool BatteryMonitor::update(void) { 1732e227fbc5ad735856ce016714440e377e85fb839Todd Poynor struct BatteryExtraProperties extraProps; 17410b235e7436256da9adc827125645f141bd8fac9Todd Poynor bool logthis; 175752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 176752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerAcOnline = false; 177752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerUsbOnline = false; 178752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerWirelessOnline = false; 179752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryStatus = BATTERY_STATUS_UNKNOWN; 180752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryHealth = BATTERY_HEALTH_UNKNOWN; 1812e227fbc5ad735856ce016714440e377e85fb839Todd Poynor extraProps.batteryCurrentNow = INT_MIN; 1822e227fbc5ad735856ce016714440e377e85fb839Todd Poynor extraProps.batteryChargeCounter = INT_MIN; 183752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 184f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (!mHealthdConfig->batteryPresentPath.isEmpty()) 185f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); 186752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor else 1876dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor props.batteryPresent = mBatteryDevicePresent; 188752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 189f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor props.batteryLevel = getIntField(mHealthdConfig->batteryCapacityPath); 190f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000; 191b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 192f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) 1932e227fbc5ad735856ce016714440e377e85fb839Todd Poynor extraProps.batteryCurrentNow = getIntField(mHealthdConfig->batteryCurrentNowPath); 194b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 1952e227fbc5ad735856ce016714440e377e85fb839Todd Poynor /* temporary while dumpsys being reworked */ 196f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) 1972e227fbc5ad735856ce016714440e377e85fb839Todd Poynor extraProps.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath); 198b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 199f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor props.batteryTemperature = getIntField(mHealthdConfig->batteryTemperaturePath); 200752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 201752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const int SIZE = 128; 202752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[SIZE]; 203752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor String8 btech; 204752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 205f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0) 206752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryStatus = getBatteryStatus(buf); 207752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 208f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0) 209752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryHealth = getBatteryHealth(buf); 210752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 211f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0) 212752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.batteryTechnology = String8(buf); 213752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 214752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor unsigned int i; 215752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 216752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor for (i = 0; i < mChargerNames.size(); i++) { 217752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor String8 path; 218752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, 219752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames[i].string()); 220752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 221752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (readFromFile(path, buf, SIZE) > 0) { 222752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (buf[0] != '0') { 223752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 224752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, 225752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames[i].string()); 226752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor switch(readPowerSupplyType(path)) { 227752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_AC: 228752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerAcOnline = true; 229752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 230752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_USB: 231752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerUsbOnline = true; 232752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 233752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: 234752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerWirelessOnline = true; 235752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 236752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor default: 237752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", 238752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames[i].string()); 239752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 240752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 241752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 242752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 243752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 24410b235e7436256da9adc827125645f141bd8fac9Todd Poynor logthis = !healthd_board_battery_update(&props); 245b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 24610b235e7436256da9adc827125645f141bd8fac9Todd Poynor if (logthis) { 24710b235e7436256da9adc827125645f141bd8fac9Todd Poynor char dmesgline[256]; 2486dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor 2496dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (props.batteryPresent) 2506dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor snprintf(dmesgline, sizeof(dmesgline), 25110b235e7436256da9adc827125645f141bd8fac9Todd Poynor "battery l=%d v=%d t=%s%d.%d h=%d st=%d", 25210b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.batteryLevel, props.batteryVoltage, 25310b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.batteryTemperature < 0 ? "-" : "", 25410b235e7436256da9adc827125645f141bd8fac9Todd Poynor abs(props.batteryTemperature / 10), 25510b235e7436256da9adc827125645f141bd8fac9Todd Poynor abs(props.batteryTemperature % 10), props.batteryHealth, 25610b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.batteryStatus); 2576dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor else 2586dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor snprintf(dmesgline, sizeof(dmesgline), 2596dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor "battery none"); 260b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 261f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 26210b235e7436256da9adc827125645f141bd8fac9Todd Poynor char b[20]; 26310b235e7436256da9adc827125645f141bd8fac9Todd Poynor 2642e227fbc5ad735856ce016714440e377e85fb839Todd Poynor snprintf(b, sizeof(b), " c=%d", extraProps.batteryCurrentNow / 1000); 26510b235e7436256da9adc827125645f141bd8fac9Todd Poynor strlcat(dmesgline, b, sizeof(dmesgline)); 26610b235e7436256da9adc827125645f141bd8fac9Todd Poynor } 267b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 26810b235e7436256da9adc827125645f141bd8fac9Todd Poynor KLOG_INFO(LOG_TAG, "%s chg=%s%s%s\n", dmesgline, 26910b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.chargerAcOnline ? "a" : "", 27010b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.chargerUsbOnline ? "u" : "", 27110b235e7436256da9adc827125645f141bd8fac9Todd Poynor props.chargerWirelessOnline ? "w" : ""); 27210b235e7436256da9adc827125645f141bd8fac9Todd Poynor } 273752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 274c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynor healthd_mode_ops->battery_update(&props); 275752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor return props.chargerAcOnline | props.chargerUsbOnline | 276752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor props.chargerWirelessOnline; 277752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 278752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 279c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynorstatus_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { 280c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor status_t ret = BAD_VALUE; 281c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 282c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor switch(id) { 283c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor case BATTERY_PROP_CHARGE_COUNTER: 284c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) { 285c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor val->valueInt = 286c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor getIntField(mHealthdConfig->batteryChargeCounterPath); 287c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NO_ERROR; 288c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } else { 289c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NAME_NOT_FOUND; 290c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } 291c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor break; 292c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 293c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor case BATTERY_PROP_CURRENT_NOW: 294c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 295c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor val->valueInt = 296c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor getIntField(mHealthdConfig->batteryCurrentNowPath); 297c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NO_ERROR; 298c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } else { 299c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor ret = NAME_NOT_FOUND; 300c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } 301c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor break; 302c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 303bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor case BATTERY_PROP_CURRENT_AVG: 304bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) { 305bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor val->valueInt = 306bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor getIntField(mHealthdConfig->batteryCurrentAvgPath); 307bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor ret = NO_ERROR; 308bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor } else { 309bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor ret = NAME_NOT_FOUND; 310bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor } 311bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor break; 312bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor 313c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor default: 314c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor break; 315c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor } 316c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 317c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor if (ret != NO_ERROR) 318c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor val->valueInt = INT_MIN; 319c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 320c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor return ret; 321c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor} 322c133b7198a02c8738aeef86d6cfd921a626adce7Todd Poynor 323020369d8724eff2b87350e54e157a609846166e4Todd Poynorvoid BatteryMonitor::dumpState(int fd) { 324020369d8724eff2b87350e54e157a609846166e4Todd Poynor int v; 325020369d8724eff2b87350e54e157a609846166e4Todd Poynor char vs[128]; 326020369d8724eff2b87350e54e157a609846166e4Todd Poynor 327020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d\n", 328020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.chargerAcOnline, props.chargerUsbOnline, 329020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.chargerWirelessOnline); 330020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 331020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", 332020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.batteryStatus, props.batteryHealth, props.batteryPresent); 333020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 334020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", 335020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.batteryLevel, props.batteryVoltage, 336020369d8724eff2b87350e54e157a609846166e4Todd Poynor props.batteryTemperature); 337020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 338020369d8724eff2b87350e54e157a609846166e4Todd Poynor 339020369d8724eff2b87350e54e157a609846166e4Todd Poynor if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 340020369d8724eff2b87350e54e157a609846166e4Todd Poynor v = getIntField(mHealthdConfig->batteryCurrentNowPath); 341020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "current now: %d\n", v); 342020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 343020369d8724eff2b87350e54e157a609846166e4Todd Poynor } 344020369d8724eff2b87350e54e157a609846166e4Todd Poynor 345020369d8724eff2b87350e54e157a609846166e4Todd Poynor if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) { 346020369d8724eff2b87350e54e157a609846166e4Todd Poynor v = getIntField(mHealthdConfig->batteryCurrentAvgPath); 347020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "current avg: %d\n", v); 348020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 349020369d8724eff2b87350e54e157a609846166e4Todd Poynor } 350020369d8724eff2b87350e54e157a609846166e4Todd Poynor 351020369d8724eff2b87350e54e157a609846166e4Todd Poynor if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) { 352020369d8724eff2b87350e54e157a609846166e4Todd Poynor v = getIntField(mHealthdConfig->batteryChargeCounterPath); 353020369d8724eff2b87350e54e157a609846166e4Todd Poynor snprintf(vs, sizeof(vs), "charge counter: %d\n", v); 354020369d8724eff2b87350e54e157a609846166e4Todd Poynor write(fd, vs, strlen(vs)); 355020369d8724eff2b87350e54e157a609846166e4Todd Poynor } 356020369d8724eff2b87350e54e157a609846166e4Todd Poynor} 357020369d8724eff2b87350e54e157a609846166e4Todd Poynor 358c7464c9150eb63ad277cc5b5f704f4fd5e6678c5Todd Poynorvoid BatteryMonitor::init(struct healthd_config *hc) { 359752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor String8 path; 360752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 361f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig = hc; 362752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH); 363752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (dir == NULL) { 364752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH); 365752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } else { 366752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor struct dirent* entry; 367752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 368752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor while ((entry = readdir(dir))) { 369752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor const char* name = entry->d_name; 370752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 371752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (!strcmp(name, ".") || !strcmp(name, "..")) 372752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor continue; 373752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 374752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor char buf[20]; 375752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor // Look for "type" file in each subdirectory 376752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 377752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name); 378752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor switch(readPowerSupplyType(path)) { 379752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_AC: 380752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_USB: 381752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: 382752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 383752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name); 384752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (access(path.string(), R_OK) == 0) 385752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor mChargerNames.add(String8(name)); 386752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 387752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 388752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_BATTERY: 3896dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor mBatteryDevicePresent = true; 3906dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor 391f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryStatusPath.isEmpty()) { 392f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 393f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH, 394f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 395f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 396f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryStatusPath = path; 397f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 398752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 399f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryHealthPath.isEmpty()) { 400752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 401f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH, 402f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 403752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (access(path, R_OK) == 0) 404f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryHealthPath = path; 405752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 406752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 407f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryPresentPath.isEmpty()) { 408f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 409f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH, 410f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 411f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 412f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryPresentPath = path; 413f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 414b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 415f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryCapacityPath.isEmpty()) { 416f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 417f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH, 418f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 419f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 420f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryCapacityPath = path; 421f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 422b45f1f5bd00c9a8380960d7c439eb14b3a334f50Todd Poynor 423f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryVoltagePath.isEmpty()) { 424f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 425f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/voltage_now", 426f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 427f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) { 428f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryVoltagePath = path; 429f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } else { 430f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 431f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/batt_vol", 432f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 433f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 434f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryVoltagePath = path; 435f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 436f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 437f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 438f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) { 439752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor path.clear(); 440f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/current_now", 441f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 442752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (access(path, R_OK) == 0) 443f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryCurrentNowPath = path; 444f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 445f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 446bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) { 447bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor path.clear(); 448bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor path.appendFormat("%s/%s/current_avg", 449bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 450bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor if (access(path, R_OK) == 0) 451bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor mHealthdConfig->batteryCurrentAvgPath = path; 452bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor } 453bc102111845a48f79a4cf6ea058a0ca334cd613cTodd Poynor 454f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) { 455f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 456f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/charge_counter", 457f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 458f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 459f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryChargeCounterPath = path; 460f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 461f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 462f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryTemperaturePath.isEmpty()) { 463f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 464f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH, 465f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor name); 466f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) { 467f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryTemperaturePath = path; 468f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } else { 469f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 470f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/batt_temp", 471f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 472f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 473f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryTemperaturePath = path; 474f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 475f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor } 476f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor 477f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (mHealthdConfig->batteryTechnologyPath.isEmpty()) { 478f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.clear(); 479f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor path.appendFormat("%s/%s/technology", 480f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor POWER_SUPPLY_SYSFS_PATH, name); 481f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor if (access(path, R_OK) == 0) 482f5d3012d2c6ac343a0b8bcc95b9cd5137d9ef02fTodd Poynor mHealthdConfig->batteryTechnologyPath = path; 483752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 484752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 485752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 486752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 487752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN: 488752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor break; 489752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 490752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 491752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor closedir(dir); 492752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor } 493752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 494752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor if (!mChargerNames.size()) 495752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor KLOG_ERROR(LOG_TAG, "No charger supplies found\n"); 4966dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (!mBatteryDevicePresent) { 4976dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_INFO(LOG_TAG, "No battery devices found\n"); 4986dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor hc->periodic_chores_interval_fast = -1; 4996dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor hc->periodic_chores_interval_slow = -1; 5006dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor } else { 5016dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryStatusPath.isEmpty()) 5026dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n"); 5036dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryHealthPath.isEmpty()) 5046dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n"); 5056dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryPresentPath.isEmpty()) 5066dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n"); 5076dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryCapacityPath.isEmpty()) 5086dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n"); 5096dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryVoltagePath.isEmpty()) 5106dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n"); 5116dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryTemperaturePath.isEmpty()) 5126dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n"); 5136dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor if (mHealthdConfig->batteryTechnologyPath.isEmpty()) 5146dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n"); 5156dcc45ed6dd455d82ecfb3addf247125846f3019Todd Poynor } 516752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor} 517752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor 518752faf2c18407fd79127fb3f3773910b4ddf669dTodd Poynor}; // namespace android 519