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;
4537a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu    jfieldID mWirelessOnline;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryStatus;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryHealth;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryPresent;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryLevel;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryVoltage;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryTemperature;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID mBatteryTechnology;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic FieldIds gFieldIds;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct BatteryManagerConstants {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusUnknown;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusCharging;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusDischarging;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusNotCharging;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint statusFull;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthUnknown;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthGood;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthOverheat;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthDead;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthOverVoltage;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint healthUnspecifiedFailure;
689239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi    jint healthCold;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic BatteryManagerConstants gConstants;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
72304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwoodstruct PowerSupplyPaths {
73304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* acOnlinePath;
74304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* usbOnlinePath;
7537a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu    char* wirelessOnlinePath;
76304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryStatusPath;
77304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryHealthPath;
78304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryPresentPath;
79304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryCapacityPath;
80304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryVoltagePath;
81304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryTemperaturePath;
82304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char* batteryTechnologyPath;
83304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood};
84304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwoodstatic PowerSupplyPaths gPaths;
85304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
86f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwoodstatic int gVoltageDivisor = 1;
87f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint getBatteryStatus(const char* status)
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (status[0]) {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'C': return gConstants.statusCharging;         // Charging
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'D': return gConstants.statusDischarging;      // Discharging
935ad9fc2182116c083f5e59a347ef1b3e487861f7Scott Anderson        case 'F': return gConstants.statusFull;             // Full
945ad9fc2182116c083f5e59a347ef1b3e487861f7Scott Anderson        case 'N': return gConstants.statusNotCharging;      // Not charging
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'U': return gConstants.statusUnknown;          // Unknown
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default: {
988564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Unknown battery status '%s'", status);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return gConstants.statusUnknown;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint getBatteryHealth(const char* status)
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (status[0]) {
1079239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi        case 'C': return gConstants.healthCold;         // Cold
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'D': return gConstants.healthDead;         // Dead
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'G': return gConstants.healthGood;         // Good
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'O': {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp(status, "Overheat") == 0) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthOverheat;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp(status, "Over voltage") == 0) {
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthOverVoltage;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1168564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Unknown battery health[1] '%s'", status);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return gConstants.healthUnknown;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'U': {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (strcmp(status, "Unspecified failure") == 0) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthUnspecifiedFailure;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (strcmp(status, "Unknown") == 0) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return gConstants.healthUnknown;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // fall through
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default: {
1308564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Unknown battery health[2] '%s'", status);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return gConstants.healthUnknown;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int readFromFile(const char* path, char* buf, size_t size)
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
138f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!path)
139f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood        return -1;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int fd = open(path, O_RDONLY, 0);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fd == -1) {
1423762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Could not open '%s'", path);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14698e044a6090fa239eca6736436d6a7efa8028066Dima Zavin    ssize_t count = read(fd, buf, size);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (count > 0) {
14898e044a6090fa239eca6736436d6a7efa8028066Dima Zavin        while (count > 0 && buf[count-1] == '\n')
14998e044a6090fa239eca6736436d6a7efa8028066Dima Zavin            count--;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[count] = '\0';
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf[0] = '\0';
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    close(fd);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return count;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int SIZE = 16;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[SIZE];
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jboolean value = false;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (readFromFile(path, buf, SIZE) > 0) {
16649016d6cd74cd6c86fa625fe8702c474f955266eAxel Haslam        if (buf[0] != '0') {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            value = true;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetBooleanField(obj, fieldID, value);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int SIZE = 128;
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[SIZE];
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint value = 0;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (readFromFile(path, buf, SIZE) > 0) {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        value = atoi(buf);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, fieldID, value);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
185f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwoodstatic void setVoltageField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
186f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood{
187f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    const int SIZE = 128;
188f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    char buf[SIZE];
189f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
190f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    jint value = 0;
191f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (readFromFile(path, buf, SIZE) > 0) {
192f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood        value = atoi(buf);
193f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood        value /= gVoltageDivisor;
194f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    }
195f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    env->SetIntField(obj, fieldID, value);
196f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood}
197f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
198f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_server_BatteryService_update(JNIEnv* env, jobject obj)
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
201304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline);
202304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);
20337a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu    setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline);
204304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
206304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
207f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
208304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int SIZE = 128;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[SIZE];
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
213304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0)
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));
215e7e6fa3fbfeae278f739f3863197d0c4fc750abeRebecca Schultz Zavin    else
216e7e6fa3fbfeae278f739f3863197d0c4fc750abeRebecca Schultz Zavin        env->SetIntField(obj, gFieldIds.mBatteryStatus,
217e7e6fa3fbfeae278f739f3863197d0c4fc750abeRebecca Schultz Zavin                         gConstants.statusUnknown);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
222304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project	{"native_update", "()V", (void*)android_server_BatteryService_update},
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_server_BatteryService(JNIEnv* env)
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
233304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    char    path[PATH_MAX];
234304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    struct dirent* entry;
235304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
236304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    DIR* dir = opendir(POWER_SUPPLY_PATH);
237304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    if (dir == NULL) {
2383762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Could not open %s\n", POWER_SUPPLY_PATH);
239a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood    } else {
240a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood        while ((entry = readdir(dir))) {
241a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            const char* name = entry->d_name;
242304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
243a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            // ignore "." and ".."
244a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
245a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                continue;
246304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood            }
247f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
248a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            char buf[20];
249a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            // Look for "type" file in each subdirectory
250a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            snprintf(path, sizeof(path), "%s/%s/type", POWER_SUPPLY_PATH, name);
251a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            int length = readFromFile(path, buf, sizeof(buf));
252a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood            if (length > 0) {
253a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                if (buf[length - 1] == '\n')
254a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    buf[length - 1] = 0;
255a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood
256a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                if (strcmp(buf, "Mains") == 0) {
257a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
258f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                    if (access(path, R_OK) == 0)
259a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.acOnlinePath = strdup(path);
260f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                }
261a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                else if (strcmp(buf, "USB") == 0) {
262a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
263f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                    if (access(path, R_OK) == 0)
264a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.usbOnlinePath = strdup(path);
265f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood                }
26637a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu                else if (strcmp(buf, "Wireless") == 0) {
26737a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
26837a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu                    if (access(path, R_OK) == 0)
26937a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu                        gPaths.wirelessOnlinePath = strdup(path);
27037a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu                }
271a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                else if (strcmp(buf, "Battery") == 0) {
272a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name);
273a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
274a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryStatusPath = strdup(path);
275a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/health", POWER_SUPPLY_PATH, name);
276a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
277a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryHealthPath = strdup(path);
278a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/present", POWER_SUPPLY_PATH, name);
279a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
280a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryPresentPath = strdup(path);
281a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name);
282a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
283a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryCapacityPath = strdup(path);
284a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood
285a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
286a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0) {
287a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryVoltagePath = strdup(path);
288a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        // voltage_now is in microvolts, not millivolts
289a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gVoltageDivisor = 1000;
290a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    } else {
291a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        snprintf(path, sizeof(path), "%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
292a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        if (access(path, R_OK) == 0)
293a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                            gPaths.batteryVoltagePath = strdup(path);
294a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    }
295a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood
296a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/temp", POWER_SUPPLY_PATH, name);
297a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0) {
298a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryTemperaturePath = strdup(path);
299a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    } else {
300a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        snprintf(path, sizeof(path), "%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
301a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        if (access(path, R_OK) == 0)
302a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                            gPaths.batteryTemperaturePath = strdup(path);
303a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    }
304f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
305a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    snprintf(path, sizeof(path), "%s/%s/technology", POWER_SUPPLY_PATH, name);
306a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                    if (access(path, R_OK) == 0)
307a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                        gPaths.batteryTechnologyPath = strdup(path);
308a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood                }
309304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood            }
310304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood        }
311a21e9455027a20c68e31358aaa1c8d9c8c28e357Mike Lockwood        closedir(dir);
312304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood    }
313304928fb7ead0efeec54b2535ed57bfc61773602Mike Lockwood
314f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.acOnlinePath)
3153762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("acOnlinePath not found");
316f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.usbOnlinePath)
3173762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("usbOnlinePath not found");
31837a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu    if (!gPaths.wirelessOnlinePath)
31937a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu        ALOGE("wirelessOnlinePath not found");
320f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryStatusPath)
3213762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryStatusPath not found");
322f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryHealthPath)
3233762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryHealthPath not found");
324f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryPresentPath)
3253762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryPresentPath not found");
326f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryCapacityPath)
3273762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryCapacityPath not found");
328f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryVoltagePath)
3293762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryVoltagePath not found");
330f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryTemperaturePath)
3313762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryTemperaturePath not found");
332f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood    if (!gPaths.batteryTechnologyPath)
3333762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("batteryTechnologyPath not found");
334f24d13a28fbf0d547ebb669f856e7c34ff70c8ecMike Lockwood
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz = env->FindClass("com/android/server/BatteryService");
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (clazz == NULL) {
3383762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find com/android/server/BatteryService");
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");
34437a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu    gFieldIds.mWirelessOnline = env->GetFieldID(clazz, "mWirelessOnline", "Z");
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH");
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mUsbOnline == NULL, "Unable to find BatteryService.USB_ONLINE_PATH");
35537a37f445cbcd64376af153dd79ea2a123d9405dBrian Muramatsu    LOG_FATAL_IF(gFieldIds.mWirelessOnline == NULL, "Unable to find BatteryService.WIRELESS_ONLINE_PATH");
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryStatus == NULL, "Unable to find BatteryService.BATTERY_STATUS_PATH");
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryHealth == NULL, "Unable to find BatteryService.BATTERY_HEALTH_PATH");
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryPresent == NULL, "Unable to find BatteryService.BATTERY_PRESENT_PATH");
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryLevel == NULL, "Unable to find BatteryService.BATTERY_CAPACITY_PATH");
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryVoltage == NULL, "Unable to find BatteryService.BATTERY_VOLTAGE_PATH");
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryTemperature == NULL, "Unable to find BatteryService.BATTERY_TEMPERATURE_PATH");
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_FATAL_IF(gFieldIds.mBatteryTechnology == NULL, "Unable to find BatteryService.BATTERY_TECHNOLOGY_PATH");
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    clazz = env->FindClass("android/os/BatteryManager");
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (clazz == NULL) {
3673762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/os/BatteryManager");
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusUnknown = env->GetStaticIntField(clazz,
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_UNKNOWN", "I"));
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusCharging = env->GetStaticIntField(clazz,
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_CHARGING", "I"));
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusDischarging = env->GetStaticIntField(clazz,
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_DISCHARGING", "I"));
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusNotCharging = env->GetStaticIntField(clazz,
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_NOT_CHARGING", "I"));
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.statusFull = env->GetStaticIntField(clazz,
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_STATUS_FULL", "I"));
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthUnknown = env->GetStaticIntField(clazz,
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNKNOWN", "I"));
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthGood = env->GetStaticIntField(clazz,
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_GOOD", "I"));
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthOverheat = env->GetStaticIntField(clazz,
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVERHEAT", "I"));
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthDead = env->GetStaticIntField(clazz,
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_DEAD", "I"));
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthOverVoltage = env->GetStaticIntField(clazz,
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVER_VOLTAGE", "I"));
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz,
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I"));
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4049239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi    gConstants.healthCold = env->GetStaticIntField(clazz,
4059239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_COLD", "I"));
4069239612870d08fbf79b3c53f11bd5d7cb4beb875Imre Sunyi
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
411