com_android_server_am_BatteryStatsService.cpp revision 0d43404a07c1372fef71181ab9daa8fa960fdd4c
1c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn/*
2c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * Copyright (C) 2014 The Android Open Source Project
3c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn *
4c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * you may not use this file except in compliance with the License.
6c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * You may obtain a copy of the License at
7c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn *
8c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn *
10c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * Unless required by applicable law or agreed to in writing, software
11c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * See the License for the specific language governing permissions and
14c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn * limitations under the License.
15c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn */
16c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
17c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#define LOG_TAG "BatteryStatsService"
18c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn//#define LOG_NDEBUG 0
19c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
200d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi#include <android/hardware/power/1.0/IPower.h>
21c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <android_runtime/AndroidRuntime.h>
22c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <jni.h>
23c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
24c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <ScopedLocalRef.h>
25c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <ScopedPrimitiveArray.h>
26c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
27c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <cutils/log.h>
28c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <utils/misc.h>
29c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <utils/Log.h>
30c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <suspend/autosuspend.h>
31c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
3268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan#include <inttypes.h>
33c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <stdio.h>
34c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <errno.h>
35c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <fcntl.h>
36c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <semaphore.h>
37c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <stddef.h>
38c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <string.h>
39c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <sys/stat.h>
40c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <sys/types.h>
41c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <unistd.h>
42c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
430d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiusing android::hardware::Return;
440d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiusing android::hardware::Void;
450d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiusing android::hardware::power::V1_0::IPower;
460d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiusing android::hardware::power::V1_0::PowerStatePlatformSleepState;
470d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiusing android::hardware::power::V1_0::PowerStateVoter;
480d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiusing android::hardware::power::V1_0::Status;
490d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiusing android::hardware::hidl_vec;
500d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi
51c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackbornnamespace android
52c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn{
53c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
54c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#define LAST_RESUME_REASON "/sys/kernel/wakeup_reasons/last_resume_reason"
55c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#define MAX_REASON_SIZE 512
56c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
57c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackbornstatic bool wakeup_init = false;
58c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackbornstatic sem_t wakeup_sem;
590d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoiextern sp<IPower> gPowerHal;
60c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
6187fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinskistatic void wakeup_callback(bool success)
62c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn{
6387fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski    ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
64c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    int ret = sem_post(&wakeup_sem);
65c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    if (ret < 0) {
66c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        char buf[80];
67c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        strerror_r(errno, buf, sizeof(buf));
68c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        ALOGE("Error posting wakeup sem: %s\n", buf);
69c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    }
70c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn}
71c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
72515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinskistatic jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
73c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn{
74515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski    if (outBuf == NULL) {
75c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        jniThrowException(env, "java/lang/NullPointerException", "null argument");
76c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        return -1;
77c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    }
78c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
79c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    // Register our wakeup callback if not yet done.
80c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    if (!wakeup_init) {
81c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        wakeup_init = true;
82c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        ALOGV("Creating semaphore...");
83c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        int ret = sem_init(&wakeup_sem, 0, 0);
84c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        if (ret < 0) {
85c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            char buf[80];
86c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            strerror_r(errno, buf, sizeof(buf));
87c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            ALOGE("Error creating semaphore: %s\n", buf);
88c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            jniThrowException(env, "java/lang/IllegalStateException", buf);
89c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            return -1;
90c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        }
91c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        ALOGV("Registering callback...");
92c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        set_wakeup_callback(&wakeup_callback);
936b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski    }
946b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski
956b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski    // Wait for wakeup.
966b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski    ALOGV("Waiting for wakeup...");
976b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski    int ret = sem_wait(&wakeup_sem);
986b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski    if (ret < 0) {
996b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski        char buf[80];
1006b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski        strerror_r(errno, buf, sizeof(buf));
1016b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski        ALOGE("Error waiting on semaphore: %s\n", buf);
1026b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski        // Return 0 here to let it continue looping but not return results.
1036b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski        return 0;
104c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    }
105c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
106c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    FILE *fp = fopen(LAST_RESUME_REASON, "r");
107c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    if (fp == NULL) {
108c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        ALOGE("Failed to open %s", LAST_RESUME_REASON);
109c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        return -1;
110c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    }
111c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
112515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski    char* mergedreason = (char*)env->GetDirectBufferAddress(outBuf);
113515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski    int remainreasonlen = (int)env->GetDirectBufferCapacity(outBuf);
114c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
115515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski    ALOGV("Reading wakeup reasons");
116c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    char* mergedreasonpos = mergedreason;
117c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    char reasonline[128];
118c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    int i = 0;
11987fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski    while (fgets(reasonline, sizeof(reasonline), fp) != NULL) {
120c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        char* pos = reasonline;
121c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        char* endPos;
12287fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski        int len;
12387fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski        // First field is the index or 'Abort'.
124c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        int irq = (int)strtol(pos, &endPos, 10);
12587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski        if (pos != endPos) {
12687fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            // Write the irq number to the merged reason string.
12787fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "%d" : ":%d", irq);
12887fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski        } else {
12987fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            // The first field is not an irq, it may be the word Abort.
13087fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            const size_t abortPrefixLen = strlen("Abort:");
13187fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            if (strncmp(pos, "Abort:", abortPrefixLen) != 0) {
13287fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski                // Ooops.
13387fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski                ALOGE("Bad reason line: %s", reasonline);
13487fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski                continue;
13587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            }
13687fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski
13787fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            // Write 'Abort' to the merged reason string.
13887fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "Abort" : ":Abort");
13987fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            endPos = pos + abortPrefixLen;
140c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        }
141c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        pos = endPos;
14287fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski
14387fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski        if (len >= 0 && len < remainreasonlen) {
14487fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            mergedreasonpos += len;
14587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski            remainreasonlen -= len;
14687fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski        }
14787fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski
148c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        // Skip whitespace; rest of the buffer is the reason string.
149c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        while (*pos == ' ') {
150c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            pos++;
151c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        }
15287fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski
153c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        // Chop newline at end.
154c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        char* endpos = pos;
155c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        while (*endpos != 0) {
156c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            if (*endpos == '\n') {
157c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn                *endpos = 0;
158c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn                break;
159c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            }
160c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            endpos++;
161c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        }
16287fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski
16387fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski        len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos);
164c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        if (len >= 0 && len < remainreasonlen) {
165c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            mergedreasonpos += len;
166c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            remainreasonlen -= len;
167c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        }
168c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        i++;
169c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    }
170c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
171c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    ALOGV("Got %d reasons", i);
172c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    if (i > 0) {
173c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        *mergedreasonpos = 0;
174c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    }
175c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
176c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    if (fclose(fp) != 0) {
177c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        ALOGE("Failed to close %s", LAST_RESUME_REASON);
178c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn        return -1;
179c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    }
180515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski    return mergedreasonpos - mergedreason;
181c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn}
182c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
18368cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharanstatic jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) {
1840d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi    char *output = (char*)env->GetDirectBufferAddress(outBuf);
1850d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi    char *offset = output;
18668cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    int remaining = (int)env->GetDirectBufferCapacity(outBuf);
18768cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    int total_added = -1;
18868cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan
18968cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    if (outBuf == NULL) {
19068cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan        jniThrowException(env, "java/lang/NullPointerException", "null argument");
1910d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi        return -1;
19268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    }
19368cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan
1940d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi    if (gPowerHal == nullptr) {
1950d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi        ALOGE("gPowerHal not loaded");
1960d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi        return -1;
19768cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    }
19868cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan
1990d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi    gPowerHal->getPlatformLowPowerStats(
2000d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi        [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
2010d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                Status status) {
2020d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi            if (status != Status::SUCCESS)
2030d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                return;
2040d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi            for (size_t i = 0; i < states.size(); i++) {
2050d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                int added;
2060d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                const PowerStatePlatformSleepState& state = states[i];
20768cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan
20815c4e31b0f7226987267656926c98d2c5d53585aBadhri Jagan Sridharan                added = snprintf(offset, remaining,
2090d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
2100d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
2110d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    state.totalTransitions);
21268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                if (added < 0) {
21368cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                    break;
21468cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                }
21568cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                if (added > remaining) {
21668cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                    added = remaining;
21768cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                }
21868cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                offset += added;
21968cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                remaining -= added;
22068cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan                total_added += added;
22168cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan
2220d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                for (size_t j = 0; j < state.voters.size(); j++) {
2230d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    const PowerStateVoter& voter = state.voters[j];
2240d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    added = snprintf(offset, remaining,
2250d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                            "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
2260d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                            j + 1, voter.name.c_str(),
2270d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                            voter.totalTimeInMsecVotedForSinceBoot,
2280d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                            voter.totalNumberOfTimesVotedSinceBoot);
2290d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    if (added < 0) {
2300d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                        break;
2310d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    }
2320d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    if (added > remaining) {
2330d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                        added = remaining;
2340d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    }
2350d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    offset += added;
2360d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    remaining -= added;
2370d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    total_added += added;
2380d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                }
2390d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi
2400d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                if (remaining <= 0) {
2410d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    /* rewrite NULL character*/
2420d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    offset--;
2430d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    total_added--;
2440d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    ALOGE("PowerHal: buffer not enough");
2450d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                    break;
2460d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi                }
24768cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan            }
24868cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan        }
2490d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi    );
25068cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    *offset = 0;
25168cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    total_added += 1;
25268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    return total_added;
25368cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan}
25468cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan
25576f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod method_table[] = {
256515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski    { "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup },
25768cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan    { "getPlatformLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getPlatformLowPowerStats },
258c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn};
259c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
260c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackbornint register_android_server_BatteryStatsService(JNIEnv *env)
261c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn{
262c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn    return jniRegisterNativeMethods(env, "com/android/server/am/BatteryStatsService",
263c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn            method_table, NELEM(method_table));
264c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn}
265c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn
266c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn};
267