Merge "Cumulative wakelock time per uid" into oc-dev
This commit is contained in:
@@ -156,6 +156,11 @@ public abstract class BatteryStats implements Parcelable {
|
||||
*/
|
||||
public static final int BLUETOOTH_SCAN_ON = 19;
|
||||
|
||||
/**
|
||||
* A constant indicating an aggregated partial wake lock timer.
|
||||
*/
|
||||
public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20;
|
||||
|
||||
/**
|
||||
* Include all of the data in the stats, including previously saved data.
|
||||
*/
|
||||
@@ -185,6 +190,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
* - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs.
|
||||
* New in version 21:
|
||||
* - Actual (not just apportioned) Wakelock time is also recorded.
|
||||
* - Aggregated partial wakelock time (per uid, instead of per wakelock) is recorded.
|
||||
*/
|
||||
static final String CHECKIN_VERSION = "21";
|
||||
|
||||
@@ -216,6 +222,10 @@ public abstract class BatteryStats implements Parcelable {
|
||||
// window totalTime, 'w', count, current duration, max duration, total duration
|
||||
// [Currently, full and window wakelocks have durations current = max = total = -1]
|
||||
private static final String WAKELOCK_DATA = "wl";
|
||||
// awl line is:
|
||||
// BATTERY_STATS_CHECKIN_VERSION, uid, which, "awl",
|
||||
// cumulative partial wakelock duration, cumulative background partial wakelock duration
|
||||
private static final String AGGREGATED_WAKELOCK_DATA = "awl";
|
||||
private static final String SYNC_DATA = "sy";
|
||||
private static final String JOB_DATA = "jb";
|
||||
private static final String KERNEL_WAKELOCK_DATA = "kwl";
|
||||
@@ -484,6 +494,13 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public abstract Timer getWakeTime(int type);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cumulative time the uid spent holding any partial wakelocks. This will generally
|
||||
* differ from summing over the Wakelocks in getWakelockStats since the latter may have
|
||||
* wakelocks that overlap in time (and therefore over-counts).
|
||||
*/
|
||||
public abstract Timer getAggregatedPartialWakelockTimer();
|
||||
|
||||
/**
|
||||
* Returns a mapping containing sensor statistics.
|
||||
*
|
||||
@@ -495,7 +512,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
* Returns a mapping containing active process data.
|
||||
*/
|
||||
public abstract SparseArray<? extends Pid> getPidStats();
|
||||
|
||||
|
||||
/**
|
||||
* Returns a mapping containing process statistics.
|
||||
*
|
||||
@@ -609,7 +626,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
static final String[] USER_ACTIVITY_TYPES = {
|
||||
"other", "button", "touch", "accessibility"
|
||||
};
|
||||
|
||||
|
||||
public static final int NUM_USER_ACTIVITY_TYPES = 4;
|
||||
|
||||
public abstract void noteUserActivityLocked(int type);
|
||||
@@ -1259,7 +1276,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public static final byte CMD_SHUTDOWN = 8;
|
||||
|
||||
public byte cmd = CMD_NULL;
|
||||
|
||||
|
||||
/**
|
||||
* Return whether the command code is a delta data update.
|
||||
*/
|
||||
@@ -1271,13 +1288,13 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public byte batteryStatus;
|
||||
public byte batteryHealth;
|
||||
public byte batteryPlugType;
|
||||
|
||||
|
||||
public short batteryTemperature;
|
||||
public char batteryVoltage;
|
||||
|
||||
// The charge of the battery in micro-Ampere-hours.
|
||||
public int batteryChargeUAh;
|
||||
|
||||
|
||||
// Constants from SCREEN_BRIGHTNESS_*
|
||||
public static final int STATE_BRIGHTNESS_SHIFT = 0;
|
||||
public static final int STATE_BRIGHTNESS_MASK = 0x7;
|
||||
@@ -1458,13 +1475,13 @@ public abstract class BatteryStats implements Parcelable {
|
||||
|
||||
public HistoryItem() {
|
||||
}
|
||||
|
||||
|
||||
public HistoryItem(long time, Parcel src) {
|
||||
this.time = time;
|
||||
numReadInts = 2;
|
||||
readFromParcel(src);
|
||||
}
|
||||
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
@@ -1560,7 +1577,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
eventCode = EVENT_NONE;
|
||||
eventTag = null;
|
||||
}
|
||||
|
||||
|
||||
public void setTo(HistoryItem o) {
|
||||
time = o.time;
|
||||
cmd = o.cmd;
|
||||
@@ -1714,7 +1731,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public final String shortName;
|
||||
public final String[] values;
|
||||
public final String[] shortValues;
|
||||
|
||||
|
||||
public BitDescription(int mask, String name, String shortName) {
|
||||
this.mask = mask;
|
||||
this.shift = -1;
|
||||
@@ -1723,7 +1740,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
this.values = null;
|
||||
this.shortValues = null;
|
||||
}
|
||||
|
||||
|
||||
public BitDescription(int mask, int shift, String name, String shortName,
|
||||
String[] values, String[] shortValues) {
|
||||
this.mask = mask;
|
||||
@@ -1771,20 +1788,20 @@ public abstract class BatteryStats implements Parcelable {
|
||||
* Return the base time offset for the battery history.
|
||||
*/
|
||||
public abstract long getHistoryBaseTime();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of times the device has been started.
|
||||
*/
|
||||
public abstract int getStartCount();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds that the screen has been on while the device was
|
||||
* running on battery.
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of times the screen was turned on.
|
||||
*
|
||||
@@ -1799,11 +1816,11 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
|
||||
public static final int SCREEN_BRIGHTNESS_LIGHT = 3;
|
||||
public static final int SCREEN_BRIGHTNESS_BRIGHT = 4;
|
||||
|
||||
|
||||
static final String[] SCREEN_BRIGHTNESS_NAMES = {
|
||||
"dark", "dim", "medium", "light", "bright"
|
||||
};
|
||||
|
||||
|
||||
static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
|
||||
"0", "1", "2", "3", "4"
|
||||
};
|
||||
@@ -1813,7 +1830,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
/**
|
||||
* Returns the time in microseconds that the screen has been on with
|
||||
* the given brightness
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getScreenBrightnessTime(int brightnessBin,
|
||||
@@ -1897,11 +1914,11 @@ public abstract class BatteryStats implements Parcelable {
|
||||
/**
|
||||
* Returns the time in microseconds that the phone has been on while the device was
|
||||
* running on battery.
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of times a phone call was activated.
|
||||
*
|
||||
@@ -1912,7 +1929,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
/**
|
||||
* Returns the time in microseconds that the phone has been running with
|
||||
* the given signal strength.
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getPhoneSignalStrengthTime(int strengthBin,
|
||||
@@ -1929,7 +1946,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
|
||||
/**
|
||||
* Returns the number of times the phone has entered the given signal strength.
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
|
||||
@@ -1997,13 +2014,13 @@ public abstract class BatteryStats implements Parcelable {
|
||||
"1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte",
|
||||
"ehrpd", "hspap", "other"
|
||||
};
|
||||
|
||||
|
||||
public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds that the phone has been running with
|
||||
* the given data connection.
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getPhoneDataConnectionTime(int dataType,
|
||||
@@ -2012,7 +2029,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
/**
|
||||
* Returns the number of times the phone has entered the given data
|
||||
* connection type.
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract int getPhoneDataConnectionCount(int dataType, int which);
|
||||
@@ -2131,7 +2148,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
/**
|
||||
* Returns the time in microseconds that wifi has been on while the device was
|
||||
* running on battery.
|
||||
*
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
|
||||
@@ -2322,7 +2339,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
* Return whether we are currently running on battery.
|
||||
*/
|
||||
public abstract boolean getIsOnBattery();
|
||||
|
||||
|
||||
/**
|
||||
* Returns a SparseArray containing the statistics for each uid.
|
||||
*/
|
||||
@@ -2341,13 +2358,13 @@ public abstract class BatteryStats implements Parcelable {
|
||||
* @param curTime the amount of elapsed realtime in microseconds.
|
||||
*/
|
||||
public abstract long getBatteryRealtime(long curTime);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the battery percentage level at the last time the device was unplugged from power, or
|
||||
* the last time it booted on battery power.
|
||||
* the last time it booted on battery power.
|
||||
*/
|
||||
public abstract int getDischargeStartLevel();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current battery percentage level if we are in a discharge cycle, otherwise
|
||||
* returns the level at the last plug event.
|
||||
@@ -2643,7 +2660,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
|
||||
final String formatBytesLocked(long bytes) {
|
||||
mFormatBuilder.setLength(0);
|
||||
|
||||
|
||||
if (bytes < BYTES_PER_KB) {
|
||||
return bytes + "B";
|
||||
} else if (bytes < BYTES_PER_MB) {
|
||||
@@ -2773,10 +2790,10 @@ public abstract class BatteryStats implements Parcelable {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checkin version of wakelock printer. Prints simple comma-separated list.
|
||||
*
|
||||
*
|
||||
* @param sb a StringBuilder object.
|
||||
* @param timer a Timer object contining the wakelock times.
|
||||
* @param elapsedRealtimeUs the current time in microseconds.
|
||||
@@ -2831,13 +2848,13 @@ public abstract class BatteryStats implements Parcelable {
|
||||
|
||||
/**
|
||||
* Dump a comma-separated line of values for terse checkin mode.
|
||||
*
|
||||
*
|
||||
* @param pw the PageWriter to dump log to
|
||||
* @param category category of data (e.g. "total", "last", "unplugged", "current" )
|
||||
* @param type type of data (e.g. "wakelock", "sensor", "process", "apk" , "process", "network")
|
||||
* @param args type-dependent data arguments
|
||||
*/
|
||||
private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
|
||||
private static final void dumpLine(PrintWriter pw, int uid, String category, String type,
|
||||
Object... args ) {
|
||||
dumpLineHeader(pw, uid, category, type);
|
||||
for (Object arg : args) {
|
||||
@@ -3014,7 +3031,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
|
||||
/**
|
||||
* Checkin server version of dump to produce more compact, computer-readable log.
|
||||
*
|
||||
*
|
||||
* NOTE: all times are expressed in 'ms'.
|
||||
*/
|
||||
public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid,
|
||||
@@ -3047,10 +3064,10 @@ public abstract class BatteryStats implements Parcelable {
|
||||
.getCountLocked(which);
|
||||
|
||||
final StringBuilder sb = new StringBuilder(128);
|
||||
|
||||
|
||||
final SparseArray<? extends Uid> uidStats = getUidStats();
|
||||
final int NU = uidStats.size();
|
||||
|
||||
|
||||
final String category = STAT_NAMES[which];
|
||||
|
||||
// Dump "battery" stat
|
||||
@@ -3063,11 +3080,11 @@ public abstract class BatteryStats implements Parcelable {
|
||||
getEstimatedBatteryCapacity(),
|
||||
getMinLearnedBatteryCapacity(), getMaxLearnedBatteryCapacity());
|
||||
|
||||
|
||||
|
||||
// Calculate wakelock times across all uids.
|
||||
long fullWakeLockTimeTotal = 0;
|
||||
long partialWakeLockTimeTotal = 0;
|
||||
|
||||
|
||||
for (int iu = 0; iu < NU; iu++) {
|
||||
final Uid u = uidStats.valueAt(iu);
|
||||
|
||||
@@ -3138,14 +3155,14 @@ public abstract class BatteryStats implements Parcelable {
|
||||
getDeviceIdlingCount(DEVICE_IDLE_MODE_LIGHT, which),
|
||||
getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_LIGHT),
|
||||
getLongestDeviceIdleModeTime(DEVICE_IDLE_MODE_DEEP));
|
||||
|
||||
|
||||
// Dump screen brightness stats
|
||||
Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
|
||||
for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
|
||||
args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
|
||||
}
|
||||
dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
|
||||
|
||||
|
||||
// Dump signal strength stats
|
||||
args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
|
||||
for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
|
||||
@@ -3207,7 +3224,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
|
||||
getDischargeCurrentLevel());
|
||||
}
|
||||
|
||||
|
||||
if (which == STATS_SINCE_UNPLUGGED) {
|
||||
dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
|
||||
getDischargeStartLevel()-getDischargeCurrentLevel(),
|
||||
@@ -3221,7 +3238,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
getDischargeAmountScreenOffSinceCharge(),
|
||||
dischargeCount / 1000, dischargeScreenOffCount / 1000);
|
||||
}
|
||||
|
||||
|
||||
if (reqUid < 0) {
|
||||
final Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
|
||||
if (kernelWakelocks.size() > 0) {
|
||||
@@ -3244,7 +3261,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly);
|
||||
helper.create(this);
|
||||
helper.refreshStats(which, UserHandle.USER_ALL);
|
||||
@@ -3434,7 +3451,17 @@ public abstract class BatteryStats implements Parcelable {
|
||||
dumpLine(pw, uid /* uid */, category, USER_ACTIVITY_DATA, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (u.getAggregatedPartialWakelockTimer() != null) {
|
||||
final Timer timer = u.getAggregatedPartialWakelockTimer();
|
||||
// Convert from microseconds to milliseconds with rounding
|
||||
final long totTimeMs = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
|
||||
final Timer bgTimer = timer.getSubTimer();
|
||||
final long bgTimeMs = bgTimer != null ?
|
||||
(bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
|
||||
dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
|
||||
}
|
||||
|
||||
final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
|
||||
for (int iw=wakelocks.size()-1; iw>=0; iw--) {
|
||||
final Uid.Wakelock wl = wakelocks.valueAt(iw);
|
||||
@@ -3666,7 +3693,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
final long chargeTimeRemaining = computeChargeTimeRemaining(rawRealtime);
|
||||
|
||||
final StringBuilder sb = new StringBuilder(128);
|
||||
|
||||
|
||||
final SparseArray<? extends Uid> uidStats = getUidStats();
|
||||
final int NU = uidStats.size();
|
||||
|
||||
@@ -3932,7 +3959,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
|
||||
final long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
|
||||
final long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
|
||||
@@ -4161,15 +4188,15 @@ public abstract class BatteryStats implements Parcelable {
|
||||
if (which == STATS_SINCE_UNPLUGGED) {
|
||||
if (getIsOnBattery()) {
|
||||
pw.print(prefix); pw.println(" Device is currently unplugged");
|
||||
pw.print(prefix); pw.print(" Discharge cycle start level: ");
|
||||
pw.print(prefix); pw.print(" Discharge cycle start level: ");
|
||||
pw.println(getDischargeStartLevel());
|
||||
pw.print(prefix); pw.print(" Discharge cycle current level: ");
|
||||
pw.println(getDischargeCurrentLevel());
|
||||
} else {
|
||||
pw.print(prefix); pw.println(" Device is currently plugged into power");
|
||||
pw.print(prefix); pw.print(" Last discharge cycle start level: ");
|
||||
pw.print(prefix); pw.print(" Last discharge cycle start level: ");
|
||||
pw.println(getDischargeStartLevel());
|
||||
pw.print(prefix); pw.print(" Last discharge cycle end level: ");
|
||||
pw.print(prefix); pw.print(" Last discharge cycle end level: ");
|
||||
pw.println(getDischargeCurrentLevel());
|
||||
}
|
||||
pw.print(prefix); pw.print(" Amount discharged while screen on: ");
|
||||
@@ -4450,7 +4477,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
final Uid u = uidStats.valueAt(iu);
|
||||
|
||||
pw.print(prefix);
|
||||
@@ -4538,7 +4565,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
formatTimeMs(sb, uidWifiRunningTime / 1000);
|
||||
sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
|
||||
whichBatteryRealtime)); sb.append(")\n");
|
||||
sb.append(prefix); sb.append(" Full Wifi Lock: ");
|
||||
sb.append(prefix); sb.append(" Full Wifi Lock: ");
|
||||
formatTimeMs(sb, fullWifiLockOnTime / 1000);
|
||||
sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
|
||||
whichBatteryRealtime)); sb.append(")\n");
|
||||
@@ -4690,8 +4717,23 @@ public abstract class BatteryStats implements Parcelable {
|
||||
rawRealtime, which);
|
||||
}
|
||||
if (countWakelock > 1) {
|
||||
if (totalFullWakelock != 0 || totalPartialWakelock != 0
|
||||
|| totalWindowWakelock != 0) {
|
||||
// get unpooled partial wakelock quantities (unlike totalPartialWakelock, which is
|
||||
// pooled and therefore just a lower bound)
|
||||
long actualTotalPartialWakelock = 0;
|
||||
long actualBgPartialWakelock = 0;
|
||||
if (u.getAggregatedPartialWakelockTimer() != null) {
|
||||
final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
|
||||
// Convert from microseconds to milliseconds with rounding
|
||||
actualTotalPartialWakelock =
|
||||
(aggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
|
||||
final Timer bgAggTimer = aggTimer.getSubTimer();
|
||||
actualBgPartialWakelock = bgAggTimer != null ?
|
||||
(bgAggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
|
||||
}
|
||||
|
||||
if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
|
||||
totalFullWakelock != 0 || totalPartialWakelock != 0 ||
|
||||
totalWindowWakelock != 0) {
|
||||
sb.setLength(0);
|
||||
sb.append(prefix);
|
||||
sb.append(" TOTAL wake: ");
|
||||
@@ -4707,7 +4749,23 @@ public abstract class BatteryStats implements Parcelable {
|
||||
}
|
||||
needComma = true;
|
||||
formatTimeMs(sb, totalPartialWakelock);
|
||||
sb.append("partial");
|
||||
sb.append("blamed partial");
|
||||
}
|
||||
if (actualTotalPartialWakelock != 0) {
|
||||
if (needComma) {
|
||||
sb.append(", ");
|
||||
}
|
||||
needComma = true;
|
||||
formatTimeMs(sb, actualTotalPartialWakelock);
|
||||
sb.append("actual partial");
|
||||
}
|
||||
if (actualBgPartialWakelock != 0) {
|
||||
if (needComma) {
|
||||
sb.append(", ");
|
||||
}
|
||||
needComma = true;
|
||||
formatTimeMs(sb, actualBgPartialWakelock);
|
||||
sb.append("actual background partial");
|
||||
}
|
||||
if (totalWindowWakelock != 0) {
|
||||
if (needComma) {
|
||||
|
||||
@@ -116,7 +116,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
|
||||
|
||||
// Current on-disk Parcel version
|
||||
private static final int VERSION = 157 + (USE_OLD_HISTORY ? 1000 : 0);
|
||||
private static final int VERSION = 158 + (USE_OLD_HISTORY ? 1000 : 0);
|
||||
|
||||
// Maximum number of items we will record in the history.
|
||||
private static final int MAX_HISTORY_ITEMS = 2000;
|
||||
@@ -3467,8 +3467,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
boolean batteryStatusChanged = mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
|
||||
|
||||
if (batteryStatusChanged) {
|
||||
for (int i=0; i<mUidStats.size(); i++) {
|
||||
mUidStats.valueAt(i).updateBgTimeBase(uptime, realtime);
|
||||
for (int i = 0; i < mUidStats.size(); i++) {
|
||||
mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3482,6 +3482,9 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
updateCpuTimeLocked();
|
||||
mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
|
||||
for (int i = 0; i < mUidStats.size(); i++) {
|
||||
mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5581,6 +5584,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
/** TimeBase for when uid is in background and device is on battery. */
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||
public final TimeBase mOnBatteryBackgroundTimeBase;
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||
public final TimeBase mOnBatteryScreenOffBackgroundTimeBase;
|
||||
|
||||
boolean mWifiRunning;
|
||||
StopwatchTimer mWifiRunningTimer;
|
||||
@@ -5603,6 +5608,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
StopwatchTimer mFlashlightTurnedOnTimer;
|
||||
StopwatchTimer mCameraTurnedOnTimer;
|
||||
StopwatchTimer mForegroundActivityTimer;
|
||||
/** Total time spent by the uid holding any partial wakelocks. */
|
||||
DualTimer mAggregatedPartialWakelockTimer;
|
||||
DualTimer mBluetoothScanTimer;
|
||||
Counter mBluetoothScanResultCounter;
|
||||
|
||||
@@ -5704,6 +5711,10 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
|
||||
mBsi.mClocks.elapsedRealtime() * 1000);
|
||||
|
||||
mOnBatteryScreenOffBackgroundTimeBase = new TimeBase();
|
||||
mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
|
||||
mBsi.mClocks.elapsedRealtime() * 1000);
|
||||
|
||||
mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
|
||||
mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
|
||||
|
||||
@@ -5773,6 +5784,11 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer getAggregatedPartialWakelockTimer() {
|
||||
return mAggregatedPartialWakelockTimer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
|
||||
return mWakelockStats.getMap();
|
||||
@@ -6062,6 +6078,15 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
return mForegroundActivityTimer;
|
||||
}
|
||||
|
||||
public DualTimer createAggregatedPartialWakelockTimerLocked() {
|
||||
if (mAggregatedPartialWakelockTimer == null) {
|
||||
mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
|
||||
AGGREGATED_WAKE_TYPE_PARTIAL, null,
|
||||
mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase);
|
||||
}
|
||||
return mAggregatedPartialWakelockTimer;
|
||||
}
|
||||
|
||||
public DualTimer createBluetoothScanTimerLocked() {
|
||||
if (mBluetoothScanTimer == null) {
|
||||
mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
|
||||
@@ -6504,6 +6529,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false);
|
||||
active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
|
||||
active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
|
||||
active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
|
||||
active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
|
||||
if (mBluetoothScanResultCounter != null) {
|
||||
mBluetoothScanResultCounter.reset(false);
|
||||
@@ -6656,6 +6682,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
|
||||
mBsi.mClocks.uptimeMillis() * 1000);
|
||||
mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
|
||||
mBsi.mClocks.uptimeMillis() * 1000);
|
||||
|
||||
if (!active) {
|
||||
if (mWifiRunningTimer != null) {
|
||||
@@ -6695,6 +6723,10 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
mForegroundActivityTimer.detach();
|
||||
mForegroundActivityTimer = null;
|
||||
}
|
||||
if (mAggregatedPartialWakelockTimer != null) {
|
||||
mAggregatedPartialWakelockTimer.detach();
|
||||
mAggregatedPartialWakelockTimer = null;
|
||||
}
|
||||
if (mBluetoothScanTimer != null) {
|
||||
mBluetoothScanTimer.detach();
|
||||
mBluetoothScanTimer = null;
|
||||
@@ -6760,6 +6792,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
|
||||
mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
|
||||
mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
|
||||
|
||||
final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
|
||||
int NW = wakeStats.size();
|
||||
@@ -6874,6 +6907,12 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
} else {
|
||||
out.writeInt(0);
|
||||
}
|
||||
if (mAggregatedPartialWakelockTimer != null) {
|
||||
out.writeInt(1);
|
||||
mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
|
||||
} else {
|
||||
out.writeInt(0);
|
||||
}
|
||||
if (mBluetoothScanTimer != null) {
|
||||
out.writeInt(1);
|
||||
mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs);
|
||||
@@ -6987,6 +7026,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
|
||||
mOnBatteryBackgroundTimeBase.readFromParcel(in);
|
||||
mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in);
|
||||
|
||||
int numWakelocks = in.readInt();
|
||||
mWakelockStats.clear();
|
||||
@@ -7112,6 +7152,14 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
} else {
|
||||
mForegroundActivityTimer = null;
|
||||
}
|
||||
if (in.readInt() != 0) {
|
||||
mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
|
||||
AGGREGATED_WAKE_TYPE_PARTIAL, null,
|
||||
mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase,
|
||||
in);
|
||||
} else {
|
||||
mAggregatedPartialWakelockTimer = null;
|
||||
}
|
||||
if (in.readInt() != 0) {
|
||||
mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
|
||||
mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
|
||||
@@ -8224,15 +8272,25 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs);
|
||||
}
|
||||
|
||||
updateBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
|
||||
updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
|
||||
updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
|
||||
}
|
||||
|
||||
public boolean updateBgTimeBase(long uptimeUs, long realtimeUs) {
|
||||
/** Whether to consider Uid to be in the background for background timebase purposes. */
|
||||
public boolean isInBackground() {
|
||||
// Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is
|
||||
// also considered to be 'background' for our purposes, because it's not foreground.
|
||||
boolean isBgAndUnplugged = mBsi.mOnBatteryTimeBase.isRunning()
|
||||
&& mProcessState >= PROCESS_STATE_BACKGROUND;
|
||||
return mOnBatteryBackgroundTimeBase.setRunning(isBgAndUnplugged, uptimeUs, realtimeUs);
|
||||
return mProcessState >= PROCESS_STATE_BACKGROUND;
|
||||
}
|
||||
|
||||
public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) {
|
||||
boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground();
|
||||
return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
|
||||
}
|
||||
|
||||
public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) {
|
||||
boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground();
|
||||
return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
|
||||
}
|
||||
|
||||
public SparseArray<? extends Pid> getPidStats() {
|
||||
@@ -8363,10 +8421,13 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
if (wl != null) {
|
||||
wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
|
||||
}
|
||||
if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
|
||||
Pid p = getPidStatsLocked(pid);
|
||||
if (p.mWakeNesting++ == 0) {
|
||||
p.mWakeStartMs = elapsedRealtimeMs;
|
||||
if (type == WAKE_TYPE_PARTIAL) {
|
||||
createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
|
||||
if (pid >= 0) {
|
||||
Pid p = getPidStatsLocked(pid);
|
||||
if (p.mWakeNesting++ == 0) {
|
||||
p.mWakeStartMs = elapsedRealtimeMs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8376,12 +8437,17 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
if (wl != null) {
|
||||
wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
|
||||
}
|
||||
if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
|
||||
Pid p = mPids.get(pid);
|
||||
if (p != null && p.mWakeNesting > 0) {
|
||||
if (p.mWakeNesting-- == 1) {
|
||||
p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
|
||||
p.mWakeStartMs = 0;
|
||||
if (type == WAKE_TYPE_PARTIAL) {
|
||||
if (mAggregatedPartialWakelockTimer != null) {
|
||||
mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
|
||||
}
|
||||
if (pid >= 0) {
|
||||
Pid p = mPids.get(pid);
|
||||
if (p != null && p.mWakeNesting > 0) {
|
||||
if (p.mWakeNesting-- == 1) {
|
||||
p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
|
||||
p.mWakeStartMs = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11265,6 +11331,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
mUidStats.put(uid, u);
|
||||
|
||||
u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in);
|
||||
u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in);
|
||||
|
||||
u.mWifiRunning = false;
|
||||
if (in.readInt() != 0) {
|
||||
@@ -11304,6 +11371,9 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
if (in.readInt() != 0) {
|
||||
u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
|
||||
}
|
||||
if (in.readInt() != 0) {
|
||||
u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in);
|
||||
}
|
||||
if (in.readInt() != 0) {
|
||||
u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
|
||||
}
|
||||
@@ -11641,6 +11711,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
Uid u = mUidStats.valueAt(iu);
|
||||
|
||||
u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
|
||||
u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
|
||||
|
||||
if (u.mWifiRunningTimer != null) {
|
||||
out.writeInt(1);
|
||||
@@ -11704,6 +11775,12 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
} else {
|
||||
out.writeInt(0);
|
||||
}
|
||||
if (u.mAggregatedPartialWakelockTimer != null) {
|
||||
out.writeInt(1);
|
||||
u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
|
||||
} else {
|
||||
out.writeInt(0);
|
||||
}
|
||||
if (u.mBluetoothScanTimer != null) {
|
||||
out.writeInt(1);
|
||||
u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
|
||||
|
||||
@@ -100,6 +100,55 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
|
||||
assertEquals(227_000, bgtb.computeRealtime(cur, STATS_SINCE_CHARGED));
|
||||
}
|
||||
|
||||
/** Test that BatteryStatsImpl.Uid.mOnBatteryScreenOffBackgroundTimeBase works correctly. */
|
||||
@SmallTest
|
||||
public void testScreenOffBgTimeBase() throws Exception {
|
||||
final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
|
||||
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
long cur = 0; // realtime in us
|
||||
|
||||
BatteryStatsImpl.TimeBase bgtb = bi.getOnBatteryScreenOffBackgroundTimeBase(UID);
|
||||
|
||||
// battery=off, screen=off, background=off
|
||||
cur = (clocks.realtime = clocks.uptime = 100) * 1000;
|
||||
bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
|
||||
bi.updateTimeBasesLocked(false, false, cur, cur);
|
||||
assertFalse(bgtb.isRunning());
|
||||
|
||||
// battery=on, screen=off, background=off
|
||||
cur = (clocks.realtime = clocks.uptime = 200) * 1000;
|
||||
bi.updateTimeBasesLocked(true, false, cur, cur);
|
||||
assertFalse(bgtb.isRunning());
|
||||
|
||||
// battery=on, screen=on, background=off
|
||||
cur = (clocks.realtime = clocks.uptime = 300) * 1000;
|
||||
bi.updateTimeBasesLocked(true, true, cur, cur);
|
||||
assertFalse(bgtb.isRunning());
|
||||
|
||||
// battery=on, screen=on, background=on
|
||||
// Only during this period should the timebase progress
|
||||
cur = (clocks.realtime = clocks.uptime = 400) * 1000;
|
||||
bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
|
||||
assertTrue(bgtb.isRunning());
|
||||
|
||||
// battery=on, screen=off, background=on
|
||||
cur = (clocks.realtime = clocks.uptime = 550) * 1000;
|
||||
bi.updateTimeBasesLocked(true, false, cur, cur);
|
||||
assertFalse(bgtb.isRunning());
|
||||
|
||||
// battery=off, screen=off, background=on
|
||||
cur = (clocks.realtime = clocks.uptime = 660) * 1000;
|
||||
bi.updateTimeBasesLocked(false, false, cur, cur);
|
||||
assertFalse(bgtb.isRunning());
|
||||
|
||||
// battery=off, screen=off, background=off
|
||||
cur = (clocks.realtime = clocks.uptime = 770) * 1000;
|
||||
bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
|
||||
assertFalse(bgtb.isRunning());
|
||||
|
||||
assertEquals(150_000, bgtb.computeRealtime(cur, STATS_SINCE_CHARGED));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testWifiScan() throws Exception {
|
||||
final MockClocks clocks = new MockClocks();
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
package com.android.internal.os;
|
||||
|
||||
import static android.os.BatteryStats.STATS_SINCE_CHARGED;
|
||||
import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.WorkSource;
|
||||
import android.support.test.filters.SmallTest;
|
||||
|
||||
@@ -29,7 +32,7 @@ public class BatteryStatsNoteTest extends TestCase{
|
||||
private static final int UID = 10500;
|
||||
private static final WorkSource WS = new WorkSource(UID);
|
||||
|
||||
/** Test that BatteryStatsImpl.Uid.noteBluetoothScanResultsLocked. */
|
||||
/** Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */
|
||||
@SmallTest
|
||||
public void testNoteBluetoothScanResultLocked() throws Exception {
|
||||
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks());
|
||||
@@ -41,4 +44,30 @@ public class BatteryStatsNoteTest extends TestCase{
|
||||
bi.getUidStats().get(UID).getBluetoothScanResultCounter()
|
||||
.getCountLocked(STATS_SINCE_CHARGED));
|
||||
}
|
||||
|
||||
/** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */
|
||||
@SmallTest
|
||||
public void testNoteStartWakeLocked() throws Exception {
|
||||
final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
|
||||
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
|
||||
int pid = 10;
|
||||
String name = "name";
|
||||
|
||||
bi.updateTimeBasesLocked(true, true, 0, 0);
|
||||
bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
|
||||
bi.getUidStatsLocked(UID).noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);
|
||||
|
||||
clocks.realtime = clocks.uptime = 100;
|
||||
bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
|
||||
|
||||
clocks.realtime = clocks.uptime = 220;
|
||||
bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);
|
||||
|
||||
BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID).getAggregatedPartialWakelockTimer();
|
||||
long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
|
||||
long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
|
||||
assertEquals(220_000, actualTime);
|
||||
assertEquals(120_000, bgTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,5 +44,9 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
|
||||
public TimeBase getOnBatteryBackgroundTimeBase(int uid) {
|
||||
return getUidStatsLocked(uid).mOnBatteryBackgroundTimeBase;
|
||||
}
|
||||
|
||||
public TimeBase getOnBatteryScreenOffBackgroundTimeBase(int uid) {
|
||||
return getUidStatsLocked(uid).mOnBatteryScreenOffBackgroundTimeBase;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user