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 2096bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <errno.h> 2196bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <fcntl.h> 2296bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <inttypes.h> 2396bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <semaphore.h> 2496bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <stddef.h> 2596bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <stdio.h> 2696bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <string.h> 2796bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <sys/stat.h> 2896bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <sys/types.h> 2996bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <unistd.h> 3096bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn 310d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi#include <android/hardware/power/1.0/IPower.h> 32c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <android_runtime/AndroidRuntime.h> 33c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <jni.h> 34c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 35c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <ScopedLocalRef.h> 36c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <ScopedPrimitiveArray.h> 37c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 3896bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <log/log.h> 39c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <utils/misc.h> 40c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <utils/Log.h> 41c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn#include <suspend/autosuspend.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; 600ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brienextern std::mutex gPowerHalMutex; 610ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brienextern bool getPowerHal(); 62c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 6387fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinskistatic void wakeup_callback(bool success) 64c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn{ 6587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted"); 66c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn int ret = sem_post(&wakeup_sem); 67c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (ret < 0) { 68c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn char buf[80]; 69c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn strerror_r(errno, buf, sizeof(buf)); 70c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn ALOGE("Error posting wakeup sem: %s\n", buf); 71c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 72c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn} 73c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 74515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinskistatic jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) 75c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn{ 76515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski if (outBuf == NULL) { 77c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn jniThrowException(env, "java/lang/NullPointerException", "null argument"); 78c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn return -1; 79c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 80c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 81c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn // Register our wakeup callback if not yet done. 82c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (!wakeup_init) { 83c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn wakeup_init = true; 84c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn ALOGV("Creating semaphore..."); 85c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn int ret = sem_init(&wakeup_sem, 0, 0); 86c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (ret < 0) { 87c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn char buf[80]; 88c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn strerror_r(errno, buf, sizeof(buf)); 89c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn ALOGE("Error creating semaphore: %s\n", buf); 90c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn jniThrowException(env, "java/lang/IllegalStateException", buf); 91c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn return -1; 92c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 93c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn ALOGV("Registering callback..."); 94c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn set_wakeup_callback(&wakeup_callback); 956b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski } 966b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski 976b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski // Wait for wakeup. 986b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski ALOGV("Waiting for wakeup..."); 996b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski int ret = sem_wait(&wakeup_sem); 1006b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski if (ret < 0) { 1016b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski char buf[80]; 1026b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski strerror_r(errno, buf, sizeof(buf)); 1036b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski ALOGE("Error waiting on semaphore: %s\n", buf); 1046b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski // Return 0 here to let it continue looping but not return results. 1056b0331a03025f2ea8c966bf9406dd5788ffa176eAdam Lesinski return 0; 106c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 107c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 108c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn FILE *fp = fopen(LAST_RESUME_REASON, "r"); 109c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (fp == NULL) { 110c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn ALOGE("Failed to open %s", LAST_RESUME_REASON); 111c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn return -1; 112c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 113c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 114515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski char* mergedreason = (char*)env->GetDirectBufferAddress(outBuf); 115515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski int remainreasonlen = (int)env->GetDirectBufferCapacity(outBuf); 116c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 117515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski ALOGV("Reading wakeup reasons"); 118c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn char* mergedreasonpos = mergedreason; 119c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn char reasonline[128]; 120c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn int i = 0; 12187fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski while (fgets(reasonline, sizeof(reasonline), fp) != NULL) { 122c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn char* pos = reasonline; 123c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn char* endPos; 12487fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski int len; 12587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski // First field is the index or 'Abort'. 126c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn int irq = (int)strtol(pos, &endPos, 10); 12787fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski if (pos != endPos) { 12887fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski // Write the irq number to the merged reason string. 12987fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "%d" : ":%d", irq); 13087fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski } else { 13187fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski // The first field is not an irq, it may be the word Abort. 13287fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski const size_t abortPrefixLen = strlen("Abort:"); 13387fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski if (strncmp(pos, "Abort:", abortPrefixLen) != 0) { 13487fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski // Ooops. 13587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski ALOGE("Bad reason line: %s", reasonline); 13687fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski continue; 13787fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski } 13887fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski 13987fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski // Write 'Abort' to the merged reason string. 14087fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski len = snprintf(mergedreasonpos, remainreasonlen, i == 0 ? "Abort" : ":Abort"); 14187fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski endPos = pos + abortPrefixLen; 142c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 143c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn pos = endPos; 14487fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski 14587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski if (len >= 0 && len < remainreasonlen) { 14687fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski mergedreasonpos += len; 14787fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski remainreasonlen -= len; 14887fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski } 14987fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski 150c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn // Skip whitespace; rest of the buffer is the reason string. 151c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn while (*pos == ' ') { 152c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn pos++; 153c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 15487fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski 155c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn // Chop newline at end. 156c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn char* endpos = pos; 157c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn while (*endpos != 0) { 158c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (*endpos == '\n') { 159c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn *endpos = 0; 160c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn break; 161c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 162c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn endpos++; 163c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 16487fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski 16587fd322ecb5cd7582f449e5b4721a1e4dea062e6Adam Lesinski len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos); 166c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (len >= 0 && len < remainreasonlen) { 167c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn mergedreasonpos += len; 168c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn remainreasonlen -= len; 169c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 170c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn i++; 171c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 172c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 173c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn ALOGV("Got %d reasons", i); 174c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (i > 0) { 175c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn *mergedreasonpos = 0; 176c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 177c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 178c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn if (fclose(fp) != 0) { 179c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn ALOGE("Failed to close %s", LAST_RESUME_REASON); 180c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn return -1; 181c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn } 182515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski return mergedreasonpos - mergedreason; 183c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn} 184c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 18568cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharanstatic jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) { 1860d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi char *output = (char*)env->GetDirectBufferAddress(outBuf); 1870d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi char *offset = output; 18868cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan int remaining = (int)env->GetDirectBufferCapacity(outBuf); 18968cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan int total_added = -1; 19068cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan 19168cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan if (outBuf == NULL) { 19268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan jniThrowException(env, "java/lang/NullPointerException", "null argument"); 1930d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi return -1; 19468cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan } 19568cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan 1960ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien { 1970ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien std::lock_guard<std::mutex> lock(gPowerHalMutex); 1980ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien if (!getPowerHal()) { 1990ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien ALOGE("Power Hal not loaded"); 2000ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien return -1; 2010ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien } 20268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan 2030ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien Return<void> ret = gPowerHal->getPlatformLowPowerStats( 2040ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states, 2050ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien Status status) { 2060ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien if (status != Status::SUCCESS) 2070ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien return; 2080ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien for (size_t i = 0; i < states.size(); i++) { 2090ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien int added; 2100ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien const PowerStatePlatformSleepState& state = states[i]; 21168cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan 2120d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi added = snprintf(offset, remaining, 2130ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", 2140ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien i + 1, state.name.c_str(), state.residencyInMsecSinceBoot, 2150ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien state.totalTransitions); 2160d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi if (added < 0) { 2170d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi break; 2180d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi } 2190d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi if (added > remaining) { 2200d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi added = remaining; 2210d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi } 2220d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi offset += added; 2230d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi remaining -= added; 2240d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi total_added += added; 2250d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi 2260ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien for (size_t j = 0; j < state.voters.size(); j++) { 2270ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien const PowerStateVoter& voter = state.voters[j]; 2280ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien added = snprintf(offset, remaining, 2290ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ", 2300ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien j + 1, voter.name.c_str(), 2310ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien voter.totalTimeInMsecVotedForSinceBoot, 2320ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien voter.totalNumberOfTimesVotedSinceBoot); 2330ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien if (added < 0) { 2340ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien break; 2350ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien } 2360ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien if (added > remaining) { 2370ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien added = remaining; 2380ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien } 2390ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien offset += added; 2400ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien remaining -= added; 2410ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien total_added += added; 2420ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien } 2430ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien 2440ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien if (remaining <= 0) { 2450ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien /* rewrite NULL character*/ 2460ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien offset--; 2470ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien total_added--; 2480ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien ALOGE("PowerHal: buffer not enough"); 2490ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien break; 2500ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien } 2510d43404a07c1372fef71181ab9daa8fa960fdd4cRuchi Kandoi } 25268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan } 2530ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien ); 2540ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien 2550ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien if (!ret.isOk()) { 2560ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien ALOGE("getPlatformLowPowerStats() failed: power HAL service not available"); 2570ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien gPowerHal = nullptr; 2580ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien return -1; 25968cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan } 2600ecd08bdd005591ef409ec65236e29db91cd0917Connor O'Brien } 26168cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan *offset = 0; 26268cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan total_added += 1; 26368cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan return total_added; 26468cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan} 26568cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan 26676f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod method_table[] = { 267515702c29e5eae0e3f02b5d65ed86218813e8945Adam Lesinski { "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup }, 26868cdf1997f7b007e4c81089bc402a0356292f4c2Badhri Jagan Sridharan { "getPlatformLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getPlatformLowPowerStats }, 269c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn}; 270c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 271c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackbornint register_android_server_BatteryStatsService(JNIEnv *env) 272c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn{ 273c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn return jniRegisterNativeMethods(env, "com/android/server/am/BatteryStatsService", 274c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn method_table, NELEM(method_table)); 275c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn} 276c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn 277c51cf03cf2458c8c137f60c7379f2cccf681d16fDianne Hackborn}; 278