19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "BatteryService"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
2125ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian#include <utils/Log.h>
2225ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian#include <utils/misc.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/socket.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <arpa/inet.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netinet/in.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h>
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
34304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood#include <dirent.h>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/ioctl.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood#define POWER_SUPPLY_PATH "/sys/class/power_supply"
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct FieldIds {
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // members
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mAcOnline;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mUsbOnline;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryStatus;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryHealth;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryPresent;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryLevel;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryVoltage;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryTemperature;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryTechnology;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic FieldIds gFieldIds;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct BatteryManagerConstants {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusUnknown;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusCharging;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusDischarging;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusNotCharging;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusFull;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthUnknown;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthGood;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthOverheat;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthDead;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthOverVoltage;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthUnspecifiedFailure;
679239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi    jint healthCold;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic BatteryManagerConstants gConstants;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
71304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwoodstruct PowerSupplyPaths {
72304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* acOnlinePath;
73304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* usbOnlinePath;
74304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryStatusPath;
75304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryHealthPath;
76304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryPresentPath;
77304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryCapacityPath;
78304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryVoltagePath;
79304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryTemperaturePath;
80304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryTechnologyPath;
81304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood};
82304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwoodstatic PowerSupplyPaths gPaths;
83304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
84f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwoodstatic int gVoltageDivisor = 1;
85f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint getBatteryStatus(const char* status)
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (status[0]) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'C': return gConstants.statusCharging;         // Charging
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'D': return gConstants.statusDischarging;      // Discharging
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'F': return gConstants.statusFull;             // Not charging
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'N': return gConstants.statusNotCharging;      // Full
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'U': return gConstants.statusUnknown;          // Unknown
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default: {
968564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Unknown battery status '%s'", status);
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return gConstants.statusUnknown;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint getBatteryHealth(const char* status)
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (status[0]) {
1059239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi        case 'C': return gConstants.healthCold;         // Cold
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'D': return gConstants.healthDead;         // Dead
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'G': return gConstants.healthGood;         // Good
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'O': {
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp(status, "Overheat") == 0) {
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthOverheat;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp(status, "Over voltage") == 0) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthOverVoltage;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1148564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Unknown battery health[1] '%s'", status);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return gConstants.healthUnknown;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'U': {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp(status, "Unspecified failure") == 0) {
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthUnspecifiedFailure;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp(status, "Unknown") == 0) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthUnknown;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // fall through
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default: {
1288564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Unknown battery health[2] '%s'", status);
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return gConstants.healthUnknown;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int readFromFile(const char* path, char* buf, size_t size)
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
136f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!path)
137f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood        return -1;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int fd = open(path, O_RDONLY, 0);
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fd == -1) {
1403762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Could not open '%s'", path);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14498e044a6090fa239eca6736436d6a7efa8028066Dima Zavin    ssize_t count = read(fd, buf, size);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (count > 0) {
14698e044a6090fa239eca6736436d6a7efa8028066Dima Zavin        while (count > 0 && buf[count-1] == '\n')
14798e044a6090fa239eca6736436d6a7efa8028066Dima Zavin            count--;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[count] = '\0';
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[0] = '\0';
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    close(fd);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return count;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int SIZE = 16;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[SIZE];
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean value = false;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (readFromFile(path, buf, SIZE) > 0) {
16449016d6cd74cd6c86fa625fe8702c474f955266eAxel Haslam        if (buf[0] != '0') {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            value = true;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetBooleanField(obj, fieldID, value);
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int SIZE = 128;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[SIZE];
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint value = 0;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (readFromFile(path, buf, SIZE) > 0) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        value = atoi(buf);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, fieldID, value);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
183f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwoodstatic void setVoltageField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
184f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood{
185f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    const int SIZE = 128;
186f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    char buf[SIZE];
187f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
188f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    jint value = 0;
189f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (readFromFile(path, buf, SIZE) > 0) {
190f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood        value = atoi(buf);
191f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood        value /= gVoltageDivisor;
192f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    }
193f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    env->SetIntField(obj, fieldID, value);
194f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood}
195f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
196f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_server_BatteryService_update(JNIEnv* env, jobject obj)
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
199304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline);
200304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);
201304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
203304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
204f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
205304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int SIZE = 128;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[SIZE];
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
210304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0)
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));
212e7e6fa3fbfeae278f739f3863197d0c4fc750abeRebecca Schultz Zavin    else
213e7e6fa3fbfeae278f739f3863197d0c4fc750abeRebecca Schultz Zavin        env->SetIntField(obj, gFieldIds.mBatteryStatus,
214e7e6fa3fbfeae278f739f3863197d0c4fc750abeRebecca Schultz Zavin                         gConstants.statusUnknown);
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
216304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_update", "()V", (void*)android_server_BatteryService_update},
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_server_BatteryService(JNIEnv* env)
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
230304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char    path[PATH_MAX];
231304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    struct dirent* entry;
232304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
233304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    DIR* dir = opendir(POWER_SUPPLY_PATH);
234304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (dir == NULL) {
2353762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Could not open %s\n", POWER_SUPPLY_PATH);
236a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood    } else {
237a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood        while ((entry = readdir(dir))) {
238a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            const char* name = entry->d_name;
239304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
240a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            // ignore "." and ".."
241a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
242a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                continue;
243304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood            }
244f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
245a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            char buf[20];
246a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            // Look for "type" file in each subdirectory
247a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            snprintf(path, sizeof(path), "%s/%s/type", POWER_SUPPLY_PATH, name);
248a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            int length = readFromFile(path, buf, sizeof(buf));
249a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            if (length > 0) {
250a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                if (buf[length - 1] == '\n')
251a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    buf[length - 1] = 0;
252a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood
253a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                if (strcmp(buf, "Mains") == 0) {
254a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
255f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                    if (access(path, R_OK) == 0)
256a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.acOnlinePath = strdup(path);
257f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                }
258a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                else if (strcmp(buf, "USB") == 0) {
259a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
260f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                    if (access(path, R_OK) == 0)
261a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.usbOnlinePath = strdup(path);
262f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                }
263a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                else if (strcmp(buf, "Battery") == 0) {
264a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name);
265a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
266a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryStatusPath = strdup(path);
267a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/health", POWER_SUPPLY_PATH, name);
268a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
269a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryHealthPath = strdup(path);
270a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/present", POWER_SUPPLY_PATH, name);
271a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
272a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryPresentPath = strdup(path);
273a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name);
274a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
275a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryCapacityPath = strdup(path);
276a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood
277a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
278a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0) {
279a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryVoltagePath = strdup(path);
280a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        // voltage_now is in microvolts, not millivolts
281a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gVoltageDivisor = 1000;
282a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    } else {
283a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        snprintf(path, sizeof(path), "%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
284a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        if (access(path, R_OK) == 0)
285a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                            gPaths.batteryVoltagePath = strdup(path);
286a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    }
287a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood
288a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/temp", POWER_SUPPLY_PATH, name);
289a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0) {
290a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryTemperaturePath = strdup(path);
291a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    } else {
292a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        snprintf(path, sizeof(path), "%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
293a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        if (access(path, R_OK) == 0)
294a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                            gPaths.batteryTemperaturePath = strdup(path);
295a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    }
296f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
297a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/technology", POWER_SUPPLY_PATH, name);
298a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
299a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryTechnologyPath = strdup(path);
300a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                }
301304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood            }
302304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood        }
303a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood        closedir(dir);
304304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    }
305304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
306f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.acOnlinePath)
3073762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("acOnlinePath not found");
308f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.usbOnlinePath)
3093762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("usbOnlinePath not found");
310f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryStatusPath)
3113762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryStatusPath not found");
312f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryHealthPath)
3133762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryHealthPath not found");
314f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryPresentPath)
3153762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryPresentPath not found");
316f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryCapacityPath)
3173762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryCapacityPath not found");
318f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryVoltagePath)
3193762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryVoltagePath not found");
320f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryTemperaturePath)
3213762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryTemperaturePath not found");
322f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryTechnologyPath)
3233762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryTechnologyPath not found");
324f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz = env->FindClass("com/android/server/BatteryService");
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (clazz == NULL) {
3283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find com/android/server/BatteryService");
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH");
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mUsbOnline == NULL, "Unable to find BatteryService.USB_ONLINE_PATH");
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryStatus == NULL, "Unable to find BatteryService.BATTERY_STATUS_PATH");
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryHealth == NULL, "Unable to find BatteryService.BATTERY_HEALTH_PATH");
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryPresent == NULL, "Unable to find BatteryService.BATTERY_PRESENT_PATH");
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryLevel == NULL, "Unable to find BatteryService.BATTERY_CAPACITY_PATH");
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryVoltage == NULL, "Unable to find BatteryService.BATTERY_VOLTAGE_PATH");
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryTemperature == NULL, "Unable to find BatteryService.BATTERY_TEMPERATURE_PATH");
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryTechnology == NULL, "Unable to find BatteryService.BATTERY_TECHNOLOGY_PATH");
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass("android/os/BatteryManager");
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (clazz == NULL) {
3553762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/os/BatteryManager");
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusUnknown = env->GetStaticIntField(clazz,
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_UNKNOWN", "I"));
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusCharging = env->GetStaticIntField(clazz,
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_CHARGING", "I"));
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusDischarging = env->GetStaticIntField(clazz,
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_DISCHARGING", "I"));
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusNotCharging = env->GetStaticIntField(clazz,
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_NOT_CHARGING", "I"));
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusFull = env->GetStaticIntField(clazz,
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_FULL", "I"));
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthUnknown = env->GetStaticIntField(clazz,
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNKNOWN", "I"));
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthGood = env->GetStaticIntField(clazz,
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_GOOD", "I"));
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthOverheat = env->GetStaticIntField(clazz,
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVERHEAT", "I"));
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthDead = env->GetStaticIntField(clazz,
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_DEAD", "I"));
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthOverVoltage = env->GetStaticIntField(clazz,
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVER_VOLTAGE", "I"));
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz,
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I"));
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3929239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi    gConstants.healthCold = env->GetStaticIntField(clazz,
3939239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_COLD", "I"));
3949239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
399