blob: 0c8b4a59427e1371dd4c24fff102f6ce4e8050d6 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BatteryService"
18
19#include "JNIHelp.h"
20#include "jni.h"
Mathias Agopian25ba5b62009-05-18 15:08:03 -070021#include <utils/Log.h>
22#include <utils/misc.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
24#include <fcntl.h>
25#include <stdio.h>
26#include <string.h>
27#include <sys/types.h>
28#include <sys/socket.h>
29#include <arpa/inet.h>
30#include <netinet/in.h>
31#include <stdlib.h>
32#include <errno.h>
33#include <unistd.h>
Mike Lockwood304928f2009-08-17 17:16:20 -040034#include <dirent.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035#include <linux/ioctl.h>
Todd Poynor701bfb12013-01-08 21:00:39 -080036#include <utils/Vector.h>
37#include <utils/String8.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038
39namespace android {
40
Mike Lockwood304928f2009-08-17 17:16:20 -040041#define POWER_SUPPLY_PATH "/sys/class/power_supply"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
43struct FieldIds {
44 // members
45 jfieldID mAcOnline;
46 jfieldID mUsbOnline;
Brian Muramatsu37a37f42012-08-14 15:21:02 -070047 jfieldID mWirelessOnline;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 jfieldID mBatteryStatus;
49 jfieldID mBatteryHealth;
50 jfieldID mBatteryPresent;
51 jfieldID mBatteryLevel;
52 jfieldID mBatteryVoltage;
53 jfieldID mBatteryTemperature;
54 jfieldID mBatteryTechnology;
55};
56static FieldIds gFieldIds;
57
58struct BatteryManagerConstants {
59 jint statusUnknown;
60 jint statusCharging;
61 jint statusDischarging;
62 jint statusNotCharging;
63 jint statusFull;
64 jint healthUnknown;
65 jint healthGood;
66 jint healthOverheat;
67 jint healthDead;
68 jint healthOverVoltage;
69 jint healthUnspecifiedFailure;
Imre Sunyi92396122010-09-20 18:02:50 +020070 jint healthCold;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071};
72static BatteryManagerConstants gConstants;
73
Mike Lockwood304928f2009-08-17 17:16:20 -040074struct PowerSupplyPaths {
Todd Poynor701bfb12013-01-08 21:00:39 -080075 String8 batteryStatusPath;
76 String8 batteryHealthPath;
77 String8 batteryPresentPath;
78 String8 batteryCapacityPath;
79 String8 batteryVoltagePath;
80 String8 batteryTemperaturePath;
81 String8 batteryTechnologyPath;
Mike Lockwood304928f2009-08-17 17:16:20 -040082};
83static PowerSupplyPaths gPaths;
84
Todd Poynor701bfb12013-01-08 21:00:39 -080085static Vector<String8> gChargerNames;
86
Mike Lockwoodf24d13a2009-08-17 18:11:14 -040087static int gVoltageDivisor = 1;
88
Todd Poynor701bfb12013-01-08 21:00:39 -080089enum PowerSupplyType {
90 ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0,
91 ANDROID_POWER_SUPPLY_TYPE_AC,
92 ANDROID_POWER_SUPPLY_TYPE_USB,
93 ANDROID_POWER_SUPPLY_TYPE_WIRELESS,
94 ANDROID_POWER_SUPPLY_TYPE_BATTERY
95};
96
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097static jint getBatteryStatus(const char* status)
98{
99 switch (status[0]) {
100 case 'C': return gConstants.statusCharging; // Charging
101 case 'D': return gConstants.statusDischarging; // Discharging
Scott Anderson5ad9fc22012-08-21 13:01:58 -0700102 case 'F': return gConstants.statusFull; // Full
103 case 'N': return gConstants.statusNotCharging; // Not charging
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 case 'U': return gConstants.statusUnknown; // Unknown
105
106 default: {
Steve Block8564c8d2012-01-05 23:22:43 +0000107 ALOGW("Unknown battery status '%s'", status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 return gConstants.statusUnknown;
109 }
110 }
111}
112
113static jint getBatteryHealth(const char* status)
114{
115 switch (status[0]) {
Imre Sunyi92396122010-09-20 18:02:50 +0200116 case 'C': return gConstants.healthCold; // Cold
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 case 'D': return gConstants.healthDead; // Dead
118 case 'G': return gConstants.healthGood; // Good
119 case 'O': {
120 if (strcmp(status, "Overheat") == 0) {
121 return gConstants.healthOverheat;
122 } else if (strcmp(status, "Over voltage") == 0) {
123 return gConstants.healthOverVoltage;
124 }
Steve Block8564c8d2012-01-05 23:22:43 +0000125 ALOGW("Unknown battery health[1] '%s'", status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 return gConstants.healthUnknown;
127 }
128
129 case 'U': {
130 if (strcmp(status, "Unspecified failure") == 0) {
131 return gConstants.healthUnspecifiedFailure;
132 } else if (strcmp(status, "Unknown") == 0) {
133 return gConstants.healthUnknown;
134 }
135 // fall through
136 }
137
138 default: {
Steve Block8564c8d2012-01-05 23:22:43 +0000139 ALOGW("Unknown battery health[2] '%s'", status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 return gConstants.healthUnknown;
141 }
142 }
143}
144
Todd Poynor701bfb12013-01-08 21:00:39 -0800145static int readFromFile(const String8& path, char* buf, size_t size)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146{
Todd Poynora6017bc2013-04-19 12:57:09 -0700147 if (path.isEmpty())
Mike Lockwoodf24d13a2009-08-17 18:11:14 -0400148 return -1;
Todd Poynor701bfb12013-01-08 21:00:39 -0800149 int fd = open(path.string(), O_RDONLY, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 if (fd == -1) {
Todd Poynor701bfb12013-01-08 21:00:39 -0800151 ALOGE("Could not open '%s'", path.string());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 return -1;
153 }
154
Dima Zavin98e044a2011-10-28 18:05:47 -0700155 ssize_t count = read(fd, buf, size);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 if (count > 0) {
Dima Zavin98e044a2011-10-28 18:05:47 -0700157 while (count > 0 && buf[count-1] == '\n')
158 count--;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 buf[count] = '\0';
160 } else {
161 buf[0] = '\0';
162 }
163
164 close(fd);
165 return count;
166}
167
Todd Poynor701bfb12013-01-08 21:00:39 -0800168static void setBooleanField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169{
170 const int SIZE = 16;
171 char buf[SIZE];
172
173 jboolean value = false;
174 if (readFromFile(path, buf, SIZE) > 0) {
Axel Haslam49016d62010-10-12 17:01:23 -0500175 if (buf[0] != '0') {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 value = true;
177 }
178 }
179 env->SetBooleanField(obj, fieldID, value);
180}
181
Todd Poynor701bfb12013-01-08 21:00:39 -0800182static void setIntField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183{
184 const int SIZE = 128;
185 char buf[SIZE];
186
187 jint value = 0;
188 if (readFromFile(path, buf, SIZE) > 0) {
189 value = atoi(buf);
190 }
191 env->SetIntField(obj, fieldID, value);
192}
193
Todd Poynor701bfb12013-01-08 21:00:39 -0800194static void setVoltageField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
Mike Lockwoodf24d13a2009-08-17 18:11:14 -0400195{
196 const int SIZE = 128;
197 char buf[SIZE];
198
199 jint value = 0;
200 if (readFromFile(path, buf, SIZE) > 0) {
201 value = atoi(buf);
202 value /= gVoltageDivisor;
203 }
204 env->SetIntField(obj, fieldID, value);
205}
206
Todd Poynor701bfb12013-01-08 21:00:39 -0800207static PowerSupplyType readPowerSupplyType(const String8& path) {
208 const int SIZE = 128;
209 char buf[SIZE];
210 int length = readFromFile(path, buf, SIZE);
211
212 if (length <= 0)
213 return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
214 if (buf[length - 1] == '\n')
215 buf[length - 1] = 0;
216 if (strcmp(buf, "Battery") == 0)
217 return ANDROID_POWER_SUPPLY_TYPE_BATTERY;
Todd Poynor78d8fe42013-01-30 14:24:12 -0800218 else if (strcmp(buf, "Mains") == 0 || strcmp(buf, "USB_DCP") == 0 ||
219 strcmp(buf, "USB_CDP") == 0 || strcmp(buf, "USB_ACA") == 0)
Todd Poynor701bfb12013-01-08 21:00:39 -0800220 return ANDROID_POWER_SUPPLY_TYPE_AC;
221 else if (strcmp(buf, "USB") == 0)
222 return ANDROID_POWER_SUPPLY_TYPE_USB;
223 else if (strcmp(buf, "Wireless") == 0)
224 return ANDROID_POWER_SUPPLY_TYPE_WIRELESS;
225 else
226 return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
227}
Mike Lockwoodf24d13a2009-08-17 18:11:14 -0400228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
230{
Mike Lockwood304928f2009-08-17 17:16:20 -0400231 setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232
Mike Lockwood304928f2009-08-17 17:16:20 -0400233 setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
Mike Lockwoodf24d13a2009-08-17 18:11:14 -0400234 setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
Mike Lockwood304928f2009-08-17 17:16:20 -0400235 setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236
237 const int SIZE = 128;
238 char buf[SIZE];
239
Mike Lockwood304928f2009-08-17 17:16:20 -0400240 if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));
Rebecca Schultz Zavine7e6fa32009-04-28 17:24:47 -0700242 else
243 env->SetIntField(obj, gFieldIds.mBatteryStatus,
244 gConstants.statusUnknown);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245
Mike Lockwood304928f2009-08-17 17:16:20 -0400246 if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));
248
Mike Lockwood304928f2009-08-17 17:16:20 -0400249 if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));
Todd Poynor701bfb12013-01-08 21:00:39 -0800251
252 unsigned int i;
253 String8 path;
254 jboolean acOnline = false;
255 jboolean usbOnline = false;
256 jboolean wirelessOnline = false;
257
258 for (i = 0; i < gChargerNames.size(); i++) {
259 path.clear();
260 path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH,
261 gChargerNames[i].string());
262
263 if (readFromFile(path, buf, SIZE) > 0) {
264 if (buf[0] != '0') {
265 path.clear();
266 path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH,
267 gChargerNames[i].string());
268 switch(readPowerSupplyType(path)) {
269 case ANDROID_POWER_SUPPLY_TYPE_AC:
270 acOnline = true;
271 break;
272 case ANDROID_POWER_SUPPLY_TYPE_USB:
273 usbOnline = true;
274 break;
275 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
276 wirelessOnline = true;
277 break;
278 default:
279 ALOGW("%s: Unknown power supply type",
280 gChargerNames[i].string());
281 }
282 }
283 }
284 }
285
286 env->SetBooleanField(obj, gFieldIds.mAcOnline, acOnline);
287 env->SetBooleanField(obj, gFieldIds.mUsbOnline, usbOnline);
288 env->SetBooleanField(obj, gFieldIds.mWirelessOnline, wirelessOnline);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289}
290
291static JNINativeMethod sMethods[] = {
292 /* name, signature, funcPtr */
Todd Poynor701bfb12013-01-08 21:00:39 -0800293 {"native_update", "()V", (void*)android_server_BatteryService_update},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294};
295
296int register_android_server_BatteryService(JNIEnv* env)
297{
Todd Poynor701bfb12013-01-08 21:00:39 -0800298 String8 path;
Mike Lockwood304928f2009-08-17 17:16:20 -0400299 struct dirent* entry;
300
301 DIR* dir = opendir(POWER_SUPPLY_PATH);
302 if (dir == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000303 ALOGE("Could not open %s\n", POWER_SUPPLY_PATH);
Mike Lockwooda21e9452011-08-16 21:23:00 -0700304 } else {
305 while ((entry = readdir(dir))) {
306 const char* name = entry->d_name;
Mike Lockwoodf24d13a2009-08-17 18:11:14 -0400307
Mike Lockwooda21e9452011-08-16 21:23:00 -0700308 // ignore "." and ".."
309 if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
310 continue;
Mike Lockwood304928f2009-08-17 17:16:20 -0400311 }
Mike Lockwoodf24d13a2009-08-17 18:11:14 -0400312
Mike Lockwooda21e9452011-08-16 21:23:00 -0700313 char buf[20];
314 // Look for "type" file in each subdirectory
Todd Poynor701bfb12013-01-08 21:00:39 -0800315 path.clear();
316 path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH, name);
317 switch(readPowerSupplyType(path)) {
318 case ANDROID_POWER_SUPPLY_TYPE_AC:
319 case ANDROID_POWER_SUPPLY_TYPE_USB:
320 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
321 path.clear();
322 path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH, name);
323 if (access(path.string(), R_OK) == 0)
324 gChargerNames.add(String8(name));
325 break;
Mike Lockwooda21e9452011-08-16 21:23:00 -0700326
Todd Poynor701bfb12013-01-08 21:00:39 -0800327 case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
328 path.clear();
329 path.appendFormat("%s/%s/status", POWER_SUPPLY_PATH, name);
330 if (access(path, R_OK) == 0)
331 gPaths.batteryStatusPath = path;
332 path.clear();
333 path.appendFormat("%s/%s/health", POWER_SUPPLY_PATH, name);
334 if (access(path, R_OK) == 0)
335 gPaths.batteryHealthPath = path;
336 path.clear();
337 path.appendFormat("%s/%s/present", POWER_SUPPLY_PATH, name);
338 if (access(path, R_OK) == 0)
339 gPaths.batteryPresentPath = path;
340 path.clear();
341 path.appendFormat("%s/%s/capacity", POWER_SUPPLY_PATH, name);
342 if (access(path, R_OK) == 0)
343 gPaths.batteryCapacityPath = path;
Mike Lockwooda21e9452011-08-16 21:23:00 -0700344
Todd Poynor701bfb12013-01-08 21:00:39 -0800345 path.clear();
346 path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
347 if (access(path, R_OK) == 0) {
348 gPaths.batteryVoltagePath = path;
349 // voltage_now is in microvolts, not millivolts
350 gVoltageDivisor = 1000;
351 } else {
352 path.clear();
353 path.appendFormat("%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
Mike Lockwooda21e9452011-08-16 21:23:00 -0700354 if (access(path, R_OK) == 0)
Todd Poynor701bfb12013-01-08 21:00:39 -0800355 gPaths.batteryVoltagePath = path;
Mike Lockwooda21e9452011-08-16 21:23:00 -0700356 }
Todd Poynor701bfb12013-01-08 21:00:39 -0800357
358 path.clear();
359 path.appendFormat("%s/%s/temp", POWER_SUPPLY_PATH, name);
360 if (access(path, R_OK) == 0) {
361 gPaths.batteryTemperaturePath = path;
362 } else {
363 path.clear();
364 path.appendFormat("%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
365 if (access(path, R_OK) == 0)
366 gPaths.batteryTemperaturePath = path;
367 }
368
369 path.clear();
370 path.appendFormat("%s/%s/technology", POWER_SUPPLY_PATH, name);
371 if (access(path, R_OK) == 0)
372 gPaths.batteryTechnologyPath = path;
373 break;
Todd Poynorb2bb9f62013-04-19 17:39:04 -0700374
375 case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
376 break;
Mike Lockwood304928f2009-08-17 17:16:20 -0400377 }
378 }
Mike Lockwooda21e9452011-08-16 21:23:00 -0700379 closedir(dir);
Mike Lockwood304928f2009-08-17 17:16:20 -0400380 }
Mike Lockwood304928f2009-08-17 17:16:20 -0400381
Todd Poynor701bfb12013-01-08 21:00:39 -0800382 if (!gChargerNames.size())
383 ALOGE("No charger supplies found");
Todd Poynora6017bc2013-04-19 12:57:09 -0700384 if (gPaths.batteryStatusPath.isEmpty())
Steve Block3762c312012-01-06 19:20:56 +0000385 ALOGE("batteryStatusPath not found");
Todd Poynora6017bc2013-04-19 12:57:09 -0700386 if (gPaths.batteryHealthPath.isEmpty())
Steve Block3762c312012-01-06 19:20:56 +0000387 ALOGE("batteryHealthPath not found");
Todd Poynora6017bc2013-04-19 12:57:09 -0700388 if (gPaths.batteryPresentPath.isEmpty())
Steve Block3762c312012-01-06 19:20:56 +0000389 ALOGE("batteryPresentPath not found");
Todd Poynora6017bc2013-04-19 12:57:09 -0700390 if (gPaths.batteryCapacityPath.isEmpty())
Steve Block3762c312012-01-06 19:20:56 +0000391 ALOGE("batteryCapacityPath not found");
Todd Poynora6017bc2013-04-19 12:57:09 -0700392 if (gPaths.batteryVoltagePath.isEmpty())
Steve Block3762c312012-01-06 19:20:56 +0000393 ALOGE("batteryVoltagePath not found");
Todd Poynora6017bc2013-04-19 12:57:09 -0700394 if (gPaths.batteryTemperaturePath.isEmpty())
Steve Block3762c312012-01-06 19:20:56 +0000395 ALOGE("batteryTemperaturePath not found");
Todd Poynora6017bc2013-04-19 12:57:09 -0700396 if (gPaths.batteryTechnologyPath.isEmpty())
Steve Block3762c312012-01-06 19:20:56 +0000397 ALOGE("batteryTechnologyPath not found");
Mike Lockwoodf24d13a2009-08-17 18:11:14 -0400398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 jclass clazz = env->FindClass("com/android/server/BatteryService");
400
401 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000402 ALOGE("Can't find com/android/server/BatteryService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 return -1;
404 }
405
406 gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
407 gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");
Brian Muramatsu37a37f42012-08-14 15:21:02 -0700408 gFieldIds.mWirelessOnline = env->GetFieldID(clazz, "mWirelessOnline", "Z");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");
410 gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");
411 gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");
412 gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
413 gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");
414 gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");
415 gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");
416
417 LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH");
418 LOG_FATAL_IF(gFieldIds.mUsbOnline == NULL, "Unable to find BatteryService.USB_ONLINE_PATH");
Brian Muramatsu37a37f42012-08-14 15:21:02 -0700419 LOG_FATAL_IF(gFieldIds.mWirelessOnline == NULL, "Unable to find BatteryService.WIRELESS_ONLINE_PATH");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 LOG_FATAL_IF(gFieldIds.mBatteryStatus == NULL, "Unable to find BatteryService.BATTERY_STATUS_PATH");
421 LOG_FATAL_IF(gFieldIds.mBatteryHealth == NULL, "Unable to find BatteryService.BATTERY_HEALTH_PATH");
422 LOG_FATAL_IF(gFieldIds.mBatteryPresent == NULL, "Unable to find BatteryService.BATTERY_PRESENT_PATH");
423 LOG_FATAL_IF(gFieldIds.mBatteryLevel == NULL, "Unable to find BatteryService.BATTERY_CAPACITY_PATH");
424 LOG_FATAL_IF(gFieldIds.mBatteryVoltage == NULL, "Unable to find BatteryService.BATTERY_VOLTAGE_PATH");
425 LOG_FATAL_IF(gFieldIds.mBatteryTemperature == NULL, "Unable to find BatteryService.BATTERY_TEMPERATURE_PATH");
426 LOG_FATAL_IF(gFieldIds.mBatteryTechnology == NULL, "Unable to find BatteryService.BATTERY_TECHNOLOGY_PATH");
427
428 clazz = env->FindClass("android/os/BatteryManager");
429
430 if (clazz == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000431 ALOGE("Can't find android/os/BatteryManager");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 return -1;
433 }
434
435 gConstants.statusUnknown = env->GetStaticIntField(clazz,
436 env->GetStaticFieldID(clazz, "BATTERY_STATUS_UNKNOWN", "I"));
437
438 gConstants.statusCharging = env->GetStaticIntField(clazz,
439 env->GetStaticFieldID(clazz, "BATTERY_STATUS_CHARGING", "I"));
440
441 gConstants.statusDischarging = env->GetStaticIntField(clazz,
442 env->GetStaticFieldID(clazz, "BATTERY_STATUS_DISCHARGING", "I"));
443
444 gConstants.statusNotCharging = env->GetStaticIntField(clazz,
445 env->GetStaticFieldID(clazz, "BATTERY_STATUS_NOT_CHARGING", "I"));
446
447 gConstants.statusFull = env->GetStaticIntField(clazz,
448 env->GetStaticFieldID(clazz, "BATTERY_STATUS_FULL", "I"));
449
450 gConstants.healthUnknown = env->GetStaticIntField(clazz,
451 env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNKNOWN", "I"));
452
453 gConstants.healthGood = env->GetStaticIntField(clazz,
454 env->GetStaticFieldID(clazz, "BATTERY_HEALTH_GOOD", "I"));
455
456 gConstants.healthOverheat = env->GetStaticIntField(clazz,
457 env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVERHEAT", "I"));
458
459 gConstants.healthDead = env->GetStaticIntField(clazz,
460 env->GetStaticFieldID(clazz, "BATTERY_HEALTH_DEAD", "I"));
461
462 gConstants.healthOverVoltage = env->GetStaticIntField(clazz,
463 env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVER_VOLTAGE", "I"));
464
465 gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz,
466 env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I"));
467
Imre Sunyi92396122010-09-20 18:02:50 +0200468 gConstants.healthCold = env->GetStaticIntField(clazz,
469 env->GetStaticFieldID(clazz, "BATTERY_HEALTH_COLD", "I"));
470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));
472}
473
474} /* namespace android */