summaryrefslogtreecommitdiffstats
path: root/services/jni/com_android_server_BatteryService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/jni/com_android_server_BatteryService.cpp')
-rw-r--r--services/jni/com_android_server_BatteryService.cpp225
1 files changed, 143 insertions, 82 deletions
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index e6133af..485c289 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -33,6 +33,8 @@
#include <unistd.h>
#include <dirent.h>
#include <linux/ioctl.h>
+#include <utils/Vector.h>
+#include <utils/String8.h>
namespace android {
@@ -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]) {
@@ -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;
}
@@ -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];
@@ -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];
@@ -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];
@@ -195,12 +204,30 @@ 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 || strcmp(buf, "USB_DCP") == 0 ||
+ strcmp(buf, "USB_CDP") == 0 || strcmp(buf, "USB_ACA") == 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);
@@ -221,16 +248,54 @@ 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[] = {
/* name, signature, funcPtr */
- {"native_update", "()V", (void*)android_server_BatteryService_update},
+ {"native_update", "()V", (void*)android_server_BatteryService_update},
};
int register_android_server_BatteryService(JNIEnv* env)
{
- char path[PATH_MAX];
+ String8 path;
struct dirent* entry;
DIR* dir = opendir(POWER_SUPPLY_PATH);
@@ -247,76 +312,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);
- 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);
+ 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.batteryStatusPath = path;
+ path.clear();
+ path.appendFormat("%s/%s/health", POWER_SUPPLY_PATH, name);
+ if (access(path, R_OK) == 0)
+ gPaths.batteryHealthPath = path;
+ path.clear();
+ path.appendFormat("%s/%s/present", POWER_SUPPLY_PATH, name);
+ if (access(path, R_OK) == 0)
+ gPaths.batteryPresentPath = path;
+ path.clear();
+ path.appendFormat("%s/%s/capacity", POWER_SUPPLY_PATH, name);
+ if (access(path, R_OK) == 0)
+ gPaths.batteryCapacityPath = path;
+
+ path.clear();
+ path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
+ if (access(path, R_OK) == 0) {
+ gPaths.batteryVoltagePath = path;
+ // voltage_now is in microvolts, not millivolts
+ gVoltageDivisor = 1000;
+ } else {
+ path.clear();
+ path.appendFormat("%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
- gPaths.usbOnlinePath = strdup(path);
+ gPaths.batteryVoltagePath = path;
}
- else if (strcmp(buf, "Wireless") == 0) {
- snprintf(path, sizeof(path), "%s/%s/online", 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);
- if (access(path, R_OK) == 0)
- gPaths.batteryStatusPath = strdup(path);
- snprintf(path, sizeof(path), "%s/%s/health", 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);
-
- snprintf(path, sizeof(path), "%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
- if (access(path, R_OK) == 0) {
- gPaths.batteryVoltagePath = strdup(path);
- // voltage_now is in microvolts, not millivolts
- gVoltageDivisor = 1000;
- } else {
- snprintf(path, sizeof(path), "%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
- if (access(path, R_OK) == 0)
- gPaths.batteryVoltagePath = strdup(path);
- }
-
- snprintf(path, sizeof(path), "%s/%s/temp", POWER_SUPPLY_PATH, name);
- if (access(path, R_OK) == 0) {
- gPaths.batteryTemperaturePath = strdup(path);
- } else {
- snprintf(path, sizeof(path), "%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
- if (access(path, R_OK) == 0)
- gPaths.batteryTemperaturePath = strdup(path);
- }
-
- snprintf(path, sizeof(path), "%s/%s/technology", POWER_SUPPLY_PATH, name);
+
+ path.clear();
+ path.appendFormat("%s/%s/temp", POWER_SUPPLY_PATH, name);
+ if (access(path, R_OK) == 0) {
+ gPaths.batteryTemperaturePath = path;
+ } else {
+ path.clear();
+ path.appendFormat("%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
- gPaths.batteryTechnologyPath = strdup(path);
+ gPaths.batteryTemperaturePath = path;
}
+
+ path.clear();
+ path.appendFormat("%s/%s/technology", POWER_SUPPLY_PATH, name);
+ if (access(path, R_OK) == 0)
+ 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)