Merge "Cumulative wakelock time per uid" into oc-dev

This commit is contained in:
Adam Bookatz
2017-05-19 18:24:31 +00:00
committed by Android (Google) Code Review
5 changed files with 292 additions and 75 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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;
}
}