diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp index e4f001fd82e51..eb5c1d1e4d54d 100644 --- a/services/jni/com_android_server_BatteryService.cpp +++ b/services/jni/com_android_server_BatteryService.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #if HAVE_ANDROID_OS #include @@ -38,15 +39,7 @@ namespace android { -#define AC_ONLINE_PATH "/sys/class/power_supply/ac/online" -#define USB_ONLINE_PATH "/sys/class/power_supply/usb/online" -#define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status" -#define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health" -#define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present" -#define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity" -#define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol" -#define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp" -#define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology" +#define POWER_SUPPLY_PATH "/sys/class/power_supply" struct FieldIds { // members @@ -77,6 +70,19 @@ struct BatteryManagerConstants { }; static BatteryManagerConstants gConstants; +struct PowerSupplyPaths { + char* acOnlinePath; + char* usbOnlinePath; + char* batteryStatusPath; + char* batteryHealthPath; + char* batteryPresentPath; + char* batteryCapacityPath; + char* batteryVoltagePath; + char* batteryTemperaturePath; + char* batteryTechnologyPath; +}; +static PowerSupplyPaths gPaths; + static jint getBatteryStatus(const char* status) { switch (status[0]) { @@ -173,27 +179,27 @@ static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fie static void android_server_BatteryService_update(JNIEnv* env, jobject obj) { - setBooleanField(env, obj, AC_ONLINE_PATH, gFieldIds.mAcOnline); - setBooleanField(env, obj, USB_ONLINE_PATH, gFieldIds.mUsbOnline); - setBooleanField(env, obj, BATTERY_PRESENT_PATH, gFieldIds.mBatteryPresent); + setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline); + setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline); + setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent); - setIntField(env, obj, BATTERY_CAPACITY_PATH, gFieldIds.mBatteryLevel); - setIntField(env, obj, BATTERY_VOLTAGE_PATH, gFieldIds.mBatteryVoltage); - setIntField(env, obj, BATTERY_TEMPERATURE_PATH, gFieldIds.mBatteryTemperature); + setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel); + setIntField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage); + setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature); const int SIZE = 128; char buf[SIZE]; - if (readFromFile(BATTERY_STATUS_PATH, buf, SIZE) > 0) + if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0) env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf)); else env->SetIntField(obj, gFieldIds.mBatteryStatus, gConstants.statusUnknown); - if (readFromFile(BATTERY_HEALTH_PATH, buf, SIZE) > 0) + if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0) env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf)); - if (readFromFile(BATTERY_TECHNOLOGY_PATH, buf, SIZE) > 0) + if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0) env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf)); } @@ -204,6 +210,51 @@ static JNINativeMethod sMethods[] = { int register_android_server_BatteryService(JNIEnv* env) { + char path[PATH_MAX]; + struct dirent* entry; + + DIR* dir = opendir(POWER_SUPPLY_PATH); + if (dir == NULL) { + LOGE("Could not open %s\n", POWER_SUPPLY_PATH); + return -1; + } + while ((entry = readdir(dir))) { + char buf[20]; + // Look for "type" file in each subdirectory + snprintf(path, sizeof(path), "%s/%s/type", POWER_SUPPLY_PATH, entry->d_name); + int length = readFromFile(path, buf, sizeof(buf)); + if (length > 0) { + if (buf[length - 1] == '\n') + buf[length - 1] = 0; + + if (strcmp(buf, "Mains") == 0) { + snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, entry->d_name); + gPaths.acOnlinePath = strdup(path); + } + else if (strcmp(buf, "USB") == 0) { + snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, entry->d_name); + gPaths.usbOnlinePath = strdup(path); + } + else if (strcmp(buf, "Battery") == 0) { + snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, entry->d_name); + gPaths.batteryStatusPath = strdup(path); + snprintf(path, sizeof(path), "%s/%s/health", POWER_SUPPLY_PATH, entry->d_name); + gPaths.batteryHealthPath = strdup(path); + snprintf(path, sizeof(path), "%s/%s/present", POWER_SUPPLY_PATH, entry->d_name); + gPaths.batteryPresentPath = strdup(path); + snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, entry->d_name); + gPaths.batteryCapacityPath = strdup(path); + snprintf(path, sizeof(path), "%s/%s/batt_vol", POWER_SUPPLY_PATH, entry->d_name); + gPaths.batteryVoltagePath = strdup(path); + snprintf(path, sizeof(path), "%s/%s/batt_temp", POWER_SUPPLY_PATH, entry->d_name); + gPaths.batteryTemperaturePath = strdup(path); + snprintf(path, sizeof(path), "%s/%s/technology", POWER_SUPPLY_PATH, entry->d_name); + gPaths.batteryTechnologyPath = strdup(path); + } + } + } + closedir(dir); + jclass clazz = env->FindClass("com/android/server/BatteryService"); if (clazz == NULL) {