Merge "Add low power stats to batteryhistory" into nyc-dev
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b9a3cff..2c63be2 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1070,6 +1070,9 @@
public int statSoftIrqTime;
public int statIdlTime;
+ // Platform-level low power state stats
+ public String statPlatformIdleState;
+
public HistoryStepDetails() {
clear();
}
@@ -1099,6 +1102,7 @@
out.writeInt(statIrqTime);
out.writeInt(statSoftIrqTime);
out.writeInt(statIdlTime);
+ out.writeString(statPlatformIdleState);
}
public void readFromParcel(Parcel in) {
@@ -1119,6 +1123,7 @@
statIrqTime = in.readInt();
statSoftIrqTime = in.readInt();
statIdlTime = in.readInt();
+ statPlatformIdleState = in.readString();
}
}
@@ -4788,6 +4793,8 @@
pw.print(sb);
pw.print(")");
}
+ pw.print(", PlatformIdleStat ");
+ pw.print(rec.stepDetails.statPlatformIdleState);
pw.println();
} else {
pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
@@ -4821,6 +4828,8 @@
pw.print(rec.stepDetails.statSoftIrqTime);
pw.print(',');
pw.print(rec.stepDetails.statIdlTime);
+ pw.print(',');
+ pw.print(rec.stepDetails.statPlatformIdleState);
pw.println();
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index e69ed35..5358d78 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -108,7 +108,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 142 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 143 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -150,6 +150,13 @@
public void batterySendBroadcast(Intent intent);
}
+ public interface PlatformIdleStateCallback {
+ public String getPlatformLowPowerStats();
+ }
+
+ private final PlatformIdleStateCallback mPlatformIdleStateCallback;
+
+
final class MyHandler extends Handler {
public MyHandler(Looper looper) {
super(looper, null, true);
@@ -569,6 +576,7 @@
mDailyFile = null;
mHandler = null;
mExternalSync = null;
+ mPlatformIdleStateCallback = null;
clearHistoryLocked();
}
@@ -2220,6 +2228,12 @@
+ cur.eventTag.string);
}
if (computeStepDetails) {
+ if (mPlatformIdleStateCallback != null) {
+ mCurHistoryStepDetails.statPlatformIdleState =
+ mPlatformIdleStateCallback.getPlatformLowPowerStats();
+ if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" +
+ mCurHistoryStepDetails.statPlatformIdleState);
+ }
computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
if (includeStepDetails != 0) {
mCurHistoryStepDetails.writeToParcel(dest);
@@ -7372,11 +7386,16 @@
}
public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
- this(new SystemClocks(), systemDir, handler, externalSync);
+ this(new SystemClocks(), systemDir, handler, externalSync, null);
+ }
+
+ public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync,
+ PlatformIdleStateCallback cb) {
+ this(new SystemClocks(), systemDir, handler, externalSync, cb);
}
public BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler,
- ExternalStatsSync externalSync) {
+ ExternalStatsSync externalSync, PlatformIdleStateCallback cb) {
init(clocks);
if (systemDir != null) {
@@ -7462,6 +7481,7 @@
initDischarge();
clearHistoryLocked();
updateDailyDeadlineLocked();
+ mPlatformIdleStateCallback = cb;
}
public BatteryStatsImpl(Parcel p) {
@@ -7477,6 +7497,7 @@
mExternalSync = null;
clearHistoryLocked();
readFromParcel(p);
+ mPlatformIdleStateCallback = null;
}
public void setPowerProfile(PowerProfile profile) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 2516f5d..c6786de 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -79,7 +79,8 @@
* battery life.
*/
public final class BatteryStatsService extends IBatteryStats.Stub
- implements PowerManagerInternal.LowPowerModeListener {
+ implements PowerManagerInternal.LowPowerModeListener,
+ BatteryStatsImpl.PlatformIdleStateCallback {
static final String TAG = "BatteryStatsService";
/**
@@ -173,6 +174,33 @@
}
}
+ private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
+ private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
+ .newDecoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE)
+ .replaceWith("?");
+ private ByteBuffer mUtf8BufferStat = ByteBuffer.allocateDirect(MAX_LOW_POWER_STATS_SIZE);
+ private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE);
+ private static final int MAX_LOW_POWER_STATS_SIZE = 512;
+
+ @Override
+ public String getPlatformLowPowerStats() {
+ mUtf8BufferStat.clear();
+ mUtf16BufferStat.clear();
+ mDecoderStat.reset();
+ int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
+ if (bytesWritten < 0) {
+ return null;
+ } else if (bytesWritten == 0) {
+ return "Empty";
+ }
+ mUtf8BufferStat.limit(bytesWritten);
+ mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
+ mUtf16BufferStat.flip();
+ return mUtf16BufferStat.toString();
+ }
+
BatteryStatsService(File systemDir, Handler handler) {
// Our handler here will be accessing the disk, use a different thread than
// what the ActivityManagerService gave us (no I/O on that one!).
@@ -182,9 +210,9 @@
mHandler = new BatteryStatsHandler(thread.getLooper());
// BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
- mStats = new BatteryStatsImpl(systemDir, handler, mHandler);
+ mStats = new BatteryStatsImpl(systemDir, handler, mHandler, this);
}
-
+
public void publish(Context context) {
mContext = context;
mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 5c43659..183a370 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -27,8 +27,10 @@
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
+#include <hardware/power.h>
#include <suspend/autosuspend.h>
+#include <inttypes.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
@@ -47,6 +49,7 @@
static bool wakeup_init = false;
static sem_t wakeup_sem;
+extern struct power_module* gPowerModule;
static void wakeup_callback(bool success)
{
@@ -170,8 +173,122 @@
return mergedreasonpos - mergedreason;
}
+static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) {
+ int num_modes = -1;
+ char *output = (char*)env->GetDirectBufferAddress(outBuf), *offset = output;
+ int remaining = (int)env->GetDirectBufferCapacity(outBuf);
+ power_state_platform_sleep_state_t *list;
+ size_t *voter_list;
+ int total_added = -1;
+
+ if (outBuf == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", "null argument");
+ goto error;
+ }
+
+ if (!gPowerModule) {
+ ALOGE("%s: gPowerModule not loaded", POWER_HARDWARE_MODULE_ID);
+ goto error;
+ }
+
+ if (! (gPowerModule->get_platform_low_power_stats && gPowerModule->get_number_of_platform_modes
+ && gPowerModule->get_voter_list)) {
+ ALOGE("%s: Missing API", POWER_HARDWARE_MODULE_ID);
+ goto error;
+ }
+
+ if (gPowerModule->get_number_of_platform_modes) {
+ num_modes = gPowerModule->get_number_of_platform_modes(gPowerModule);
+ }
+
+ if (num_modes < 1) {
+ ALOGE("%s: Platform does not even have one low power mode", POWER_HARDWARE_MODULE_ID);
+ goto error;
+ }
+
+ list = (power_state_platform_sleep_state_t *)calloc(num_modes,
+ sizeof(power_state_platform_sleep_state_t));
+ if (!list) {
+ ALOGE("%s: power_state_platform_sleep_state_t allocation failed", POWER_HARDWARE_MODULE_ID);
+ goto error;
+ }
+
+ voter_list = (size_t *)calloc(num_modes, sizeof(*voter_list));
+ if (!voter_list) {
+ ALOGE("%s: voter_list allocation failed", POWER_HARDWARE_MODULE_ID);
+ goto err_free;
+ }
+
+ gPowerModule->get_voter_list(gPowerModule, voter_list);
+
+ for (int i = 0; i < num_modes; i++) {
+ list[i].voters = (power_state_voter_t *)calloc(voter_list[i],
+ sizeof(power_state_voter_t));
+ if (!list[i].voters) {
+ ALOGE("%s: voter_t allocation failed", POWER_HARDWARE_MODULE_ID);
+ goto err_free;
+ }
+ }
+
+ if (!gPowerModule->get_platform_low_power_stats(gPowerModule, list)) {
+ for (int i = 0; i < num_modes; i++) {
+ int added;
+
+ added = snprintf(offset, remaining, "%s_time=%" PRIu64 " %s_count=%" PRIu64 " ",
+ list[i].name, list[i].residency_in_msec_since_boot, list[i].name,
+ list[i].total_transitions);
+ if (added < 0) {
+ break;
+ }
+ if (added > remaining) {
+ added = remaining;
+ }
+ offset += added;
+ remaining -= added;
+ total_added += added;
+
+ for (unsigned int j = 0; j < list[i].number_of_voters; j++) {
+ added = snprintf(offset, remaining, "%s_time=%" PRIu64 " %s_count=%" PRIu64 " ",
+ list[i].voters[j].name,
+ list[i].voters[j].total_time_in_msec_voted_for_since_boot,
+ list[i].voters[j].name,
+ list[i].voters[j].total_number_of_times_voted_since_boot);
+ if (added < 0) {
+ break;
+ }
+ if (added > remaining) {
+ added = remaining;
+ }
+ offset += added;
+ remaining -= added;
+ total_added += added;
+ }
+
+ if (remaining <= 0) {
+ /* rewrite NULL character*/
+ offset--;
+ total_added--;
+ ALOGE("%s module: buffer not enough", POWER_HARDWARE_MODULE_ID);
+ break;
+ }
+ }
+ }
+ *offset = 0;
+ total_added += 1;
+
+err_free:
+ for (int i = 0; i < num_modes; i++) {
+ free(list[i].voters);
+ }
+ free(list);
+ free(voter_list);
+error:
+ return total_added;
+}
+
static const JNINativeMethod method_table[] = {
{ "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup },
+ { "getPlatformLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getPlatformLowPowerStats },
};
int register_android_server_BatteryStatsService(JNIEnv *env)
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 2fdb8e2..cbbfda6a 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -48,7 +48,7 @@
// ----------------------------------------------------------------------------
static jobject gPowerManagerServiceObj;
-static struct power_module* gPowerModule;
+struct power_module* gPowerModule;
static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];