Merge "Add tron counter for battery % too"
This commit is contained in:
committed by
Android (Google) Code Review
commit
35501be16f
@@ -34,7 +34,7 @@ option java_package com.android.server
|
||||
2731 power_soft_sleep_requested (savedwaketimems|2)
|
||||
# Power save state has changed. See BatterySaverController.java for the details.
|
||||
2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5)
|
||||
27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|6),(total_duration|2|3),(total_battery_drain|1|6)
|
||||
27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|1),(delta_battery_drain_percent|1|6),(total_duration|2|3),(total_battery_drain|1|1),(total_battery_drain_percent|1|6)
|
||||
|
||||
#
|
||||
# Leave IDs through 2740 for more power logs (2730 used by battery_discharge above)
|
||||
|
||||
@@ -32,6 +32,8 @@ import java.io.PrintWriter;
|
||||
/**
|
||||
* This class keeps track of battery drain rate.
|
||||
*
|
||||
* TODO: The use of the terms "percent" and "level" in this class is not standard. Fix it.
|
||||
*
|
||||
* Test:
|
||||
atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java
|
||||
*/
|
||||
@@ -96,8 +98,12 @@ public class BatterySavingStats {
|
||||
public int startBatteryLevel;
|
||||
public int endBatteryLevel;
|
||||
|
||||
public int startBatteryPercent;
|
||||
public int endBatteryPercent;
|
||||
|
||||
public long totalTimeMillis;
|
||||
public int totalBatteryDrain;
|
||||
public int totalBatteryDrainPercent;
|
||||
|
||||
public long totalMinutes() {
|
||||
return totalTimeMillis / 60_000;
|
||||
@@ -110,13 +116,25 @@ public class BatterySavingStats {
|
||||
return (double) totalBatteryDrain / (totalTimeMillis / (60.0 * 60 * 1000));
|
||||
}
|
||||
|
||||
public double drainPercentPerHour() {
|
||||
if (totalTimeMillis == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (double) totalBatteryDrainPercent / (totalTimeMillis / (60.0 * 60 * 1000));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
String toStringForTest() {
|
||||
return "{" + totalMinutes() + "m," + totalBatteryDrain + ","
|
||||
+ String.format("%.2f", drainPerHour()) + "}";
|
||||
+ String.format("%.2f", drainPerHour()) + "uA/H,"
|
||||
+ String.format("%.2f", drainPercentPerHour()) + "%"
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static final String COUNTER_POWER_PERCENT_PREFIX = "battery_saver_stats_percent_";
|
||||
|
||||
@VisibleForTesting
|
||||
static final String COUNTER_POWER_MILLIAMPS_PREFIX = "battery_saver_stats_milliamps_";
|
||||
|
||||
@@ -166,6 +184,9 @@ public class BatterySavingStats {
|
||||
private BatteryManagerInternal getBatteryManagerInternal() {
|
||||
if (mBatteryManagerInternal == null) {
|
||||
mBatteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class);
|
||||
if (mBatteryManagerInternal == null) {
|
||||
Slog.wtf(TAG, "BatteryManagerInternal not initialized");
|
||||
}
|
||||
}
|
||||
return mBatteryManagerInternal;
|
||||
}
|
||||
@@ -229,12 +250,20 @@ public class BatterySavingStats {
|
||||
int injectBatteryLevel() {
|
||||
final BatteryManagerInternal bmi = getBatteryManagerInternal();
|
||||
if (bmi == null) {
|
||||
Slog.wtf(TAG, "BatteryManagerInternal not initialized");
|
||||
return 0;
|
||||
}
|
||||
return bmi.getBatteryChargeCounter();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
int injectBatteryPercent() {
|
||||
final BatteryManagerInternal bmi = getBatteryManagerInternal();
|
||||
if (bmi == null) {
|
||||
return 0;
|
||||
}
|
||||
return bmi.getBatteryLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the outside whenever any of the states changes, when the device is not plugged
|
||||
* in.
|
||||
@@ -262,33 +291,39 @@ public class BatterySavingStats {
|
||||
}
|
||||
final long now = injectCurrentTime();
|
||||
final int batteryLevel = injectBatteryLevel();
|
||||
final int batteryPercent = injectBatteryPercent();
|
||||
|
||||
endLastStateLocked(now, batteryLevel);
|
||||
startNewStateLocked(newState, now, batteryLevel);
|
||||
mMetricsLoggerHelper.transitionState(newState, now, batteryLevel);
|
||||
endLastStateLocked(now, batteryLevel, batteryPercent);
|
||||
startNewStateLocked(newState, now, batteryLevel, batteryPercent);
|
||||
mMetricsLoggerHelper.transitionState(newState, now, batteryLevel, batteryPercent);
|
||||
}
|
||||
|
||||
private void endLastStateLocked(long now, int batteryLevel) {
|
||||
private void endLastStateLocked(long now, int batteryLevel, int batteryPercent) {
|
||||
if (mCurrentState < 0) {
|
||||
return;
|
||||
}
|
||||
final Stat stat = getStat(mCurrentState);
|
||||
|
||||
stat.endBatteryLevel = batteryLevel;
|
||||
stat.endBatteryPercent = batteryPercent;
|
||||
stat.endTime = now;
|
||||
|
||||
final long deltaTime = stat.endTime - stat.startTime;
|
||||
final int deltaDrain = stat.startBatteryLevel - stat.endBatteryLevel;
|
||||
final int deltaPercent = stat.startBatteryPercent - stat.endBatteryPercent;
|
||||
|
||||
stat.totalTimeMillis += deltaTime;
|
||||
stat.totalBatteryDrain += deltaDrain;
|
||||
stat.totalBatteryDrainPercent += deltaPercent;
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "State summary: " + stateToString(mCurrentState)
|
||||
+ ": " + (deltaTime / 1_000) + "s "
|
||||
+ "Start level: " + stat.startBatteryLevel + "uA "
|
||||
+ "End level: " + stat.endBatteryLevel + "uA "
|
||||
+ deltaDrain + "uA");
|
||||
+ "Start percent: " + stat.startBatteryPercent + "% "
|
||||
+ "End percent: " + stat.endBatteryPercent + "% "
|
||||
+ "Drain " + deltaDrain + "uA");
|
||||
}
|
||||
EventLogTags.writeBatterySavingStats(
|
||||
BatterySaverState.fromIndex(mCurrentState),
|
||||
@@ -296,12 +331,14 @@ public class BatterySavingStats {
|
||||
DozeState.fromIndex(mCurrentState),
|
||||
deltaTime,
|
||||
deltaDrain,
|
||||
deltaPercent,
|
||||
stat.totalTimeMillis,
|
||||
stat.totalBatteryDrain);
|
||||
stat.totalBatteryDrain,
|
||||
stat.totalBatteryDrainPercent);
|
||||
|
||||
}
|
||||
|
||||
private void startNewStateLocked(int newState, long now, int batteryLevel) {
|
||||
private void startNewStateLocked(int newState, long now, int batteryLevel, int batteryPercent) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "New state: " + stateToString(newState));
|
||||
}
|
||||
@@ -313,6 +350,7 @@ public class BatterySavingStats {
|
||||
|
||||
final Stat stat = getStat(mCurrentState);
|
||||
stat.startBatteryLevel = batteryLevel;
|
||||
stat.startBatteryPercent = batteryPercent;
|
||||
stat.startTime = now;
|
||||
stat.endTime = 0;
|
||||
}
|
||||
@@ -325,7 +363,7 @@ public class BatterySavingStats {
|
||||
indent = indent + " ";
|
||||
|
||||
pw.print(indent);
|
||||
pw.println("Battery Saver: Off On");
|
||||
pw.println("Battery Saver: Off On");
|
||||
dumpLineLocked(pw, indent, InteractiveState.NON_INTERACTIVE, "NonIntr",
|
||||
DozeState.NOT_DOZING, "NonDoze");
|
||||
dumpLineLocked(pw, indent, InteractiveState.INTERACTIVE, " Intr",
|
||||
@@ -357,12 +395,14 @@ public class BatterySavingStats {
|
||||
final Stat offStat = getStat(BatterySaverState.OFF, interactiveState, dozeState);
|
||||
final Stat onStat = getStat(BatterySaverState.ON, interactiveState, dozeState);
|
||||
|
||||
pw.println(String.format("%6dm %6dmA %8.1fmA/h %6dm %6dmA %8.1fmA/h",
|
||||
pw.println(String.format("%6dm %6dmA (%3d%%) %8.1fmA/h %6dm %6dmA (%3d%%) %8.1fmA/h",
|
||||
offStat.totalMinutes(),
|
||||
offStat.totalBatteryDrain / 1000,
|
||||
offStat.totalBatteryDrainPercent,
|
||||
offStat.drainPerHour() / 1000.0,
|
||||
onStat.totalMinutes(),
|
||||
onStat.totalBatteryDrain / 1000,
|
||||
onStat.totalBatteryDrainPercent,
|
||||
onStat.drainPerHour() / 1000.0));
|
||||
}
|
||||
|
||||
@@ -371,12 +411,13 @@ public class BatterySavingStats {
|
||||
private int mLastState = STATE_NOT_INITIALIZED;
|
||||
private long mStartTime;
|
||||
private int mStartBatteryLevel;
|
||||
private int mStartPercent;
|
||||
|
||||
private static final int STATE_CHANGE_DETECT_MASK =
|
||||
(BatterySaverState.MASK << BatterySaverState.SHIFT) |
|
||||
(InteractiveState.MASK << InteractiveState.SHIFT);
|
||||
|
||||
public void transitionState(int newState, long now, int batteryLevel) {
|
||||
public void transitionState(int newState, long now, int batteryLevel, int batteryPercent) {
|
||||
final boolean stateChanging =
|
||||
((mLastState >= 0) ^ (newState >= 0)) ||
|
||||
(((mLastState ^ newState) & STATE_CHANGE_DETECT_MASK) != 0);
|
||||
@@ -384,11 +425,13 @@ public class BatterySavingStats {
|
||||
if (mLastState >= 0) {
|
||||
final long deltaTime = now - mStartTime;
|
||||
final int deltaBattery = mStartBatteryLevel - batteryLevel;
|
||||
final int deltaPercent = mStartPercent - batteryPercent;
|
||||
|
||||
report(mLastState, deltaTime, deltaBattery);
|
||||
report(mLastState, deltaTime, deltaBattery, deltaPercent);
|
||||
}
|
||||
mStartTime = now;
|
||||
mStartBatteryLevel = batteryLevel;
|
||||
mStartPercent = batteryPercent;
|
||||
}
|
||||
mLastState = newState;
|
||||
}
|
||||
@@ -405,9 +448,10 @@ public class BatterySavingStats {
|
||||
}
|
||||
}
|
||||
|
||||
void report(int state, long deltaTimeMs, int deltaBatteryUa) {
|
||||
void report(int state, long deltaTimeMs, int deltaBatteryUa, int deltaPercent) {
|
||||
final String suffix = getCounterSuffix(state);
|
||||
mMetricsLogger.count(COUNTER_POWER_MILLIAMPS_PREFIX + suffix, deltaBatteryUa / 1000);
|
||||
mMetricsLogger.count(COUNTER_POWER_PERCENT_PREFIX + suffix, deltaPercent);
|
||||
mMetricsLogger.count(COUNTER_TIME_SECONDS_PREFIX + suffix, (int) (deltaTimeMs / 1000));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,11 @@ public class BatterySavingStatsTest {
|
||||
return mBatteryLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
int injectBatteryPercent() {
|
||||
return mBatteryLevel / 10;
|
||||
}
|
||||
|
||||
void assertDumpable() {
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
dump(new PrintWriter(out), ""); // Just make sure it won't crash.
|
||||
@@ -102,7 +107,7 @@ public class BatterySavingStatsTest {
|
||||
target.assertDumpable();
|
||||
|
||||
target.advanceClock(1);
|
||||
target.drainBattery(2);
|
||||
target.drainBattery(200);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -110,7 +115,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(4);
|
||||
target.drainBattery(1);
|
||||
target.drainBattery(100);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -118,7 +123,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(2);
|
||||
target.drainBattery(5);
|
||||
target.drainBattery(500);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -126,7 +131,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(4);
|
||||
target.drainBattery(1);
|
||||
target.drainBattery(100);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -134,7 +139,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(2);
|
||||
target.drainBattery(5);
|
||||
target.drainBattery(500);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -142,7 +147,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(3);
|
||||
target.drainBattery(1);
|
||||
target.drainBattery(100);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -150,7 +155,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.LIGHT);
|
||||
|
||||
target.advanceClock(5);
|
||||
target.drainBattery(1);
|
||||
target.drainBattery(100);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -158,7 +163,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.DEEP);
|
||||
|
||||
target.advanceClock(1);
|
||||
target.drainBattery(2);
|
||||
target.drainBattery(200);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.ON,
|
||||
@@ -166,7 +171,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(1);
|
||||
target.drainBattery(3);
|
||||
target.drainBattery(300);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.OFF,
|
||||
@@ -174,7 +179,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(3);
|
||||
target.drainBattery(5);
|
||||
target.drainBattery(500);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.ON,
|
||||
@@ -182,12 +187,12 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(3);
|
||||
target.drainBattery(5);
|
||||
target.drainBattery(500);
|
||||
|
||||
target.startCharging();
|
||||
|
||||
target.advanceClock(5);
|
||||
target.drainBattery(10);
|
||||
target.drainBattery(1000);
|
||||
|
||||
target.transitionState(
|
||||
BatterySaverState.ON,
|
||||
@@ -195,25 +200,25 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
target.advanceClock(5);
|
||||
target.drainBattery(1);
|
||||
target.drainBattery(100);
|
||||
|
||||
target.startCharging();
|
||||
|
||||
target.assertDumpable();
|
||||
|
||||
assertEquals(
|
||||
"BS=0,I=0,D=0:{4m,10,150.00}\n" +
|
||||
"BS=1,I=0,D=0:{0m,0,0.00}\n" +
|
||||
"BS=0,I=1,D=0:{14m,8,34.29}\n" +
|
||||
"BS=1,I=1,D=0:{9m,9,60.00}\n" +
|
||||
"BS=0,I=0,D=1:{5m,1,12.00}\n" +
|
||||
"BS=1,I=0,D=1:{0m,0,0.00}\n" +
|
||||
"BS=0,I=1,D=1:{0m,0,0.00}\n" +
|
||||
"BS=1,I=1,D=1:{0m,0,0.00}\n" +
|
||||
"BS=0,I=0,D=2:{1m,2,120.00}\n" +
|
||||
"BS=1,I=0,D=2:{0m,0,0.00}\n" +
|
||||
"BS=0,I=1,D=2:{0m,0,0.00}\n" +
|
||||
"BS=1,I=1,D=2:{0m,0,0.00}",
|
||||
"BS=0,I=0,D=0:{4m,1000,15000.00uA/H,1500.00%}\n" +
|
||||
"BS=1,I=0,D=0:{0m,0,0.00uA/H,0.00%}\n" +
|
||||
"BS=0,I=1,D=0:{14m,800,3428.57uA/H,342.86%}\n" +
|
||||
"BS=1,I=1,D=0:{9m,900,6000.00uA/H,600.00%}\n" +
|
||||
"BS=0,I=0,D=1:{5m,100,1200.00uA/H,120.00%}\n" +
|
||||
"BS=1,I=0,D=1:{0m,0,0.00uA/H,0.00%}\n" +
|
||||
"BS=0,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" +
|
||||
"BS=1,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" +
|
||||
"BS=0,I=0,D=2:{1m,200,12000.00uA/H,1200.00%}\n" +
|
||||
"BS=1,I=0,D=2:{0m,0,0.00uA/H,0.00%}\n" +
|
||||
"BS=0,I=1,D=2:{0m,0,0.00uA/H,0.00%}\n" +
|
||||
"BS=1,I=1,D=2:{0m,0,0.00uA/H,0.00%}",
|
||||
target.toDebugString());
|
||||
}
|
||||
|
||||
@@ -245,6 +250,7 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "01", 2);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "01", 200);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "01", 60);
|
||||
|
||||
target.advanceClock(1);
|
||||
@@ -277,15 +283,17 @@ public class BatterySavingStatsTest {
|
||||
DozeState.NOT_DOZING);
|
||||
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "00", 2 * 3);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "00", 200 * 3);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "00", 60 * 3);
|
||||
|
||||
target.advanceClock(10);
|
||||
target.drainBattery(10_000);
|
||||
target.drainBattery(10000);
|
||||
|
||||
reset(mMetricsLogger);
|
||||
target.startCharging();
|
||||
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "11", 10);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "11", 1000);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "11", 60 * 10);
|
||||
|
||||
target.advanceClock(1);
|
||||
@@ -305,6 +313,7 @@ public class BatterySavingStatsTest {
|
||||
target.startCharging();
|
||||
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "10", 2);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "10", 200);
|
||||
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "10", 60);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user