Loading services/jni/com_android_server_BatteryService.cpp +142 −82 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <unistd.h> #include <dirent.h> #include <linux/ioctl.h> #include <utils/Vector.h> #include <utils/String8.h> namespace android { Loading Loading @@ -70,21 +72,28 @@ struct BatteryManagerConstants { static BatteryManagerConstants gConstants; struct PowerSupplyPaths { char* acOnlinePath; char* usbOnlinePath; char* wirelessOnlinePath; char* batteryStatusPath; char* batteryHealthPath; char* batteryPresentPath; char* batteryCapacityPath; char* batteryVoltagePath; char* batteryTemperaturePath; char* batteryTechnologyPath; String8 batteryStatusPath; String8 batteryHealthPath; String8 batteryPresentPath; String8 batteryCapacityPath; String8 batteryVoltagePath; String8 batteryTemperaturePath; String8 batteryTechnologyPath; }; static PowerSupplyPaths gPaths; static Vector<String8> gChargerNames; static int gVoltageDivisor = 1; enum PowerSupplyType { ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0, ANDROID_POWER_SUPPLY_TYPE_AC, ANDROID_POWER_SUPPLY_TYPE_USB, ANDROID_POWER_SUPPLY_TYPE_WIRELESS, ANDROID_POWER_SUPPLY_TYPE_BATTERY }; static jint getBatteryStatus(const char* status) { switch (status[0]) { Loading Loading @@ -133,13 +142,13 @@ static jint getBatteryHealth(const char* status) } } static int readFromFile(const char* path, char* buf, size_t size) static int readFromFile(const String8& path, char* buf, size_t size) { if (!path) return -1; int fd = open(path, O_RDONLY, 0); int fd = open(path.string(), O_RDONLY, 0); if (fd == -1) { ALOGE("Could not open '%s'", path); ALOGE("Could not open '%s'", path.string()); return -1; } Loading @@ -156,7 +165,7 @@ static int readFromFile(const char* path, char* buf, size_t size) return count; } static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) static void setBooleanField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID) { const int SIZE = 16; char buf[SIZE]; Loading @@ -170,7 +179,7 @@ static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID env->SetBooleanField(obj, fieldID, value); } static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) static void setIntField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID) { const int SIZE = 128; char buf[SIZE]; Loading @@ -182,7 +191,7 @@ static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fie env->SetIntField(obj, fieldID, value); } static void setVoltageField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) static void setVoltageField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID) { const int SIZE = 128; char buf[SIZE]; Loading @@ -195,12 +204,29 @@ static void setVoltageField(JNIEnv* env, jobject obj, const char* path, jfieldID env->SetIntField(obj, fieldID, value); } static PowerSupplyType readPowerSupplyType(const String8& path) { const int SIZE = 128; char buf[SIZE]; int length = readFromFile(path, buf, SIZE); if (length <= 0) return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; if (buf[length - 1] == '\n') buf[length - 1] = 0; if (strcmp(buf, "Battery") == 0) return ANDROID_POWER_SUPPLY_TYPE_BATTERY; else if (strcmp(buf, "Mains") == 0) return ANDROID_POWER_SUPPLY_TYPE_AC; else if (strcmp(buf, "USB") == 0) return ANDROID_POWER_SUPPLY_TYPE_USB; else if (strcmp(buf, "Wireless") == 0) return ANDROID_POWER_SUPPLY_TYPE_WIRELESS; else return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; } static void android_server_BatteryService_update(JNIEnv* env, jobject obj) { setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline); setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline); setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline); setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent); setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel); Loading @@ -221,6 +247,44 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj) if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0) env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf)); unsigned int i; String8 path; jboolean acOnline = false; jboolean usbOnline = false; jboolean wirelessOnline = false; for (i = 0; i < gChargerNames.size(); i++) { path.clear(); path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH, gChargerNames[i].string()); if (readFromFile(path, buf, SIZE) > 0) { if (buf[0] != '0') { path.clear(); path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH, gChargerNames[i].string()); switch(readPowerSupplyType(path)) { case ANDROID_POWER_SUPPLY_TYPE_AC: acOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_USB: usbOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: wirelessOnline = true; break; default: ALOGW("%s: Unknown power supply type", gChargerNames[i].string()); } } } } env->SetBooleanField(obj, gFieldIds.mAcOnline, acOnline); env->SetBooleanField(obj, gFieldIds.mUsbOnline, usbOnline); env->SetBooleanField(obj, gFieldIds.mWirelessOnline, wirelessOnline); } static JNINativeMethod sMethods[] = { Loading @@ -230,7 +294,7 @@ static JNINativeMethod sMethods[] = { int register_android_server_BatteryService(JNIEnv* env) { char path[PATH_MAX]; String8 path; struct dirent* entry; DIR* dir = opendir(POWER_SUPPLY_PATH); Loading @@ -247,76 +311,72 @@ int register_android_server_BatteryService(JNIEnv* env) char buf[20]; // Look for "type" file in each subdirectory snprintf(path, sizeof(path), "%s/%s/type", POWER_SUPPLY_PATH, 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, name); path.clear(); path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH, name); switch(readPowerSupplyType(path)) { case ANDROID_POWER_SUPPLY_TYPE_AC: case ANDROID_POWER_SUPPLY_TYPE_USB: case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: path.clear(); path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH, name); if (access(path.string(), R_OK) == 0) gChargerNames.add(String8(name)); break; case ANDROID_POWER_SUPPLY_TYPE_BATTERY: path.clear(); path.appendFormat("%s/%s/status", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.acOnlinePath = strdup(path); } else if (strcmp(buf, "USB") == 0) { snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.usbOnlinePath = strdup(path); } else if (strcmp(buf, "Wireless") == 0) { snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name); gPaths.batteryStatusPath = path; path.clear(); path.appendFormat("%s/%s/health", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.wirelessOnlinePath = strdup(path); } else if (strcmp(buf, "Battery") == 0) { snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name); gPaths.batteryHealthPath = path; path.clear(); path.appendFormat("%s/%s/present", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryStatusPath = strdup(path); snprintf(path, sizeof(path), "%s/%s/health", POWER_SUPPLY_PATH, name); gPaths.batteryPresentPath = path; path.clear(); path.appendFormat("%s/%s/capacity", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryHealthPath = strdup(path); snprintf(path, sizeof(path), "%s/%s/present", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryPresentPath = strdup(path); snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryCapacityPath = strdup(path); gPaths.batteryCapacityPath = path; snprintf(path, sizeof(path), "%s/%s/voltage_now", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) { gPaths.batteryVoltagePath = strdup(path); gPaths.batteryVoltagePath = path; // voltage_now is in microvolts, not millivolts gVoltageDivisor = 1000; } else { snprintf(path, sizeof(path), "%s/%s/batt_vol", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/batt_vol", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryVoltagePath = strdup(path); gPaths.batteryVoltagePath = path; } snprintf(path, sizeof(path), "%s/%s/temp", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/temp", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) { gPaths.batteryTemperaturePath = strdup(path); gPaths.batteryTemperaturePath = path; } else { snprintf(path, sizeof(path), "%s/%s/batt_temp", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/batt_temp", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryTemperaturePath = strdup(path); gPaths.batteryTemperaturePath = path; } snprintf(path, sizeof(path), "%s/%s/technology", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/technology", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryTechnologyPath = strdup(path); } gPaths.batteryTechnologyPath = path; break; } } closedir(dir); } if (!gPaths.acOnlinePath) ALOGE("acOnlinePath not found"); if (!gPaths.usbOnlinePath) ALOGE("usbOnlinePath not found"); if (!gPaths.wirelessOnlinePath) ALOGE("wirelessOnlinePath not found"); if (!gChargerNames.size()) ALOGE("No charger supplies found"); if (!gPaths.batteryStatusPath) ALOGE("batteryStatusPath not found"); if (!gPaths.batteryHealthPath) Loading Loading
services/jni/com_android_server_BatteryService.cpp +142 −82 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <unistd.h> #include <dirent.h> #include <linux/ioctl.h> #include <utils/Vector.h> #include <utils/String8.h> namespace android { Loading Loading @@ -70,21 +72,28 @@ struct BatteryManagerConstants { static BatteryManagerConstants gConstants; struct PowerSupplyPaths { char* acOnlinePath; char* usbOnlinePath; char* wirelessOnlinePath; char* batteryStatusPath; char* batteryHealthPath; char* batteryPresentPath; char* batteryCapacityPath; char* batteryVoltagePath; char* batteryTemperaturePath; char* batteryTechnologyPath; String8 batteryStatusPath; String8 batteryHealthPath; String8 batteryPresentPath; String8 batteryCapacityPath; String8 batteryVoltagePath; String8 batteryTemperaturePath; String8 batteryTechnologyPath; }; static PowerSupplyPaths gPaths; static Vector<String8> gChargerNames; static int gVoltageDivisor = 1; enum PowerSupplyType { ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0, ANDROID_POWER_SUPPLY_TYPE_AC, ANDROID_POWER_SUPPLY_TYPE_USB, ANDROID_POWER_SUPPLY_TYPE_WIRELESS, ANDROID_POWER_SUPPLY_TYPE_BATTERY }; static jint getBatteryStatus(const char* status) { switch (status[0]) { Loading Loading @@ -133,13 +142,13 @@ static jint getBatteryHealth(const char* status) } } static int readFromFile(const char* path, char* buf, size_t size) static int readFromFile(const String8& path, char* buf, size_t size) { if (!path) return -1; int fd = open(path, O_RDONLY, 0); int fd = open(path.string(), O_RDONLY, 0); if (fd == -1) { ALOGE("Could not open '%s'", path); ALOGE("Could not open '%s'", path.string()); return -1; } Loading @@ -156,7 +165,7 @@ static int readFromFile(const char* path, char* buf, size_t size) return count; } static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) static void setBooleanField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID) { const int SIZE = 16; char buf[SIZE]; Loading @@ -170,7 +179,7 @@ static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID env->SetBooleanField(obj, fieldID, value); } static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) static void setIntField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID) { const int SIZE = 128; char buf[SIZE]; Loading @@ -182,7 +191,7 @@ static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fie env->SetIntField(obj, fieldID, value); } static void setVoltageField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID) static void setVoltageField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID) { const int SIZE = 128; char buf[SIZE]; Loading @@ -195,12 +204,29 @@ static void setVoltageField(JNIEnv* env, jobject obj, const char* path, jfieldID env->SetIntField(obj, fieldID, value); } static PowerSupplyType readPowerSupplyType(const String8& path) { const int SIZE = 128; char buf[SIZE]; int length = readFromFile(path, buf, SIZE); if (length <= 0) return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; if (buf[length - 1] == '\n') buf[length - 1] = 0; if (strcmp(buf, "Battery") == 0) return ANDROID_POWER_SUPPLY_TYPE_BATTERY; else if (strcmp(buf, "Mains") == 0) return ANDROID_POWER_SUPPLY_TYPE_AC; else if (strcmp(buf, "USB") == 0) return ANDROID_POWER_SUPPLY_TYPE_USB; else if (strcmp(buf, "Wireless") == 0) return ANDROID_POWER_SUPPLY_TYPE_WIRELESS; else return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN; } static void android_server_BatteryService_update(JNIEnv* env, jobject obj) { setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline); setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline); setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline); setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent); setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel); Loading @@ -221,6 +247,44 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj) if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0) env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf)); unsigned int i; String8 path; jboolean acOnline = false; jboolean usbOnline = false; jboolean wirelessOnline = false; for (i = 0; i < gChargerNames.size(); i++) { path.clear(); path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH, gChargerNames[i].string()); if (readFromFile(path, buf, SIZE) > 0) { if (buf[0] != '0') { path.clear(); path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH, gChargerNames[i].string()); switch(readPowerSupplyType(path)) { case ANDROID_POWER_SUPPLY_TYPE_AC: acOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_USB: usbOnline = true; break; case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: wirelessOnline = true; break; default: ALOGW("%s: Unknown power supply type", gChargerNames[i].string()); } } } } env->SetBooleanField(obj, gFieldIds.mAcOnline, acOnline); env->SetBooleanField(obj, gFieldIds.mUsbOnline, usbOnline); env->SetBooleanField(obj, gFieldIds.mWirelessOnline, wirelessOnline); } static JNINativeMethod sMethods[] = { Loading @@ -230,7 +294,7 @@ static JNINativeMethod sMethods[] = { int register_android_server_BatteryService(JNIEnv* env) { char path[PATH_MAX]; String8 path; struct dirent* entry; DIR* dir = opendir(POWER_SUPPLY_PATH); Loading @@ -247,76 +311,72 @@ int register_android_server_BatteryService(JNIEnv* env) char buf[20]; // Look for "type" file in each subdirectory snprintf(path, sizeof(path), "%s/%s/type", POWER_SUPPLY_PATH, 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, name); path.clear(); path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH, name); switch(readPowerSupplyType(path)) { case ANDROID_POWER_SUPPLY_TYPE_AC: case ANDROID_POWER_SUPPLY_TYPE_USB: case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: path.clear(); path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH, name); if (access(path.string(), R_OK) == 0) gChargerNames.add(String8(name)); break; case ANDROID_POWER_SUPPLY_TYPE_BATTERY: path.clear(); path.appendFormat("%s/%s/status", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.acOnlinePath = strdup(path); } else if (strcmp(buf, "USB") == 0) { snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.usbOnlinePath = strdup(path); } else if (strcmp(buf, "Wireless") == 0) { snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name); gPaths.batteryStatusPath = path; path.clear(); path.appendFormat("%s/%s/health", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.wirelessOnlinePath = strdup(path); } else if (strcmp(buf, "Battery") == 0) { snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name); gPaths.batteryHealthPath = path; path.clear(); path.appendFormat("%s/%s/present", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryStatusPath = strdup(path); snprintf(path, sizeof(path), "%s/%s/health", POWER_SUPPLY_PATH, name); gPaths.batteryPresentPath = path; path.clear(); path.appendFormat("%s/%s/capacity", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryHealthPath = strdup(path); snprintf(path, sizeof(path), "%s/%s/present", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryPresentPath = strdup(path); snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryCapacityPath = strdup(path); gPaths.batteryCapacityPath = path; snprintf(path, sizeof(path), "%s/%s/voltage_now", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) { gPaths.batteryVoltagePath = strdup(path); gPaths.batteryVoltagePath = path; // voltage_now is in microvolts, not millivolts gVoltageDivisor = 1000; } else { snprintf(path, sizeof(path), "%s/%s/batt_vol", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/batt_vol", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryVoltagePath = strdup(path); gPaths.batteryVoltagePath = path; } snprintf(path, sizeof(path), "%s/%s/temp", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/temp", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) { gPaths.batteryTemperaturePath = strdup(path); gPaths.batteryTemperaturePath = path; } else { snprintf(path, sizeof(path), "%s/%s/batt_temp", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/batt_temp", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryTemperaturePath = strdup(path); gPaths.batteryTemperaturePath = path; } snprintf(path, sizeof(path), "%s/%s/technology", POWER_SUPPLY_PATH, name); path.clear(); path.appendFormat("%s/%s/technology", POWER_SUPPLY_PATH, name); if (access(path, R_OK) == 0) gPaths.batteryTechnologyPath = strdup(path); } gPaths.batteryTechnologyPath = path; break; } } closedir(dir); } if (!gPaths.acOnlinePath) ALOGE("acOnlinePath not found"); if (!gPaths.usbOnlinePath) ALOGE("usbOnlinePath not found"); if (!gPaths.wirelessOnlinePath) ALOGE("wirelessOnlinePath not found"); if (!gChargerNames.size()) ALOGE("No charger supplies found"); if (!gPaths.batteryStatusPath) ALOGE("batteryStatusPath not found"); if (!gPaths.batteryHealthPath) Loading