Merge "Update BatteryStatsImpl to handle multidisplay" into sc-v2-dev am: 684c0b4a77
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15913462 Change-Id: Id788a5ca13e871baa85bb2ada6ead28b50170e55
This commit is contained in:
committed by
Automerger Merge Worker
commit
05c4ff8a0c
@@ -2302,6 +2302,38 @@ public abstract class BatteryStats implements Parcelable {
|
||||
*/
|
||||
public abstract Timer getScreenBrightnessTimer(int brightnessBin);
|
||||
|
||||
/**
|
||||
* Returns the number of physical displays on the device.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract int getDisplayCount();
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds that the screen has been on for a display while the
|
||||
* device was running on battery.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getDisplayScreenOnTime(int display, long elapsedRealtimeUs);
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds that a display has been dozing while the device was
|
||||
* running on battery.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs);
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds that a display has been on with the given brightness
|
||||
* level while the device was running on battery.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getDisplayScreenBrightnessTime(int display, int brightnessBin,
|
||||
long elapsedRealtimeUs);
|
||||
|
||||
/**
|
||||
* Returns the time in microseconds that power save mode has been enabled while the device was
|
||||
* running on battery.
|
||||
@@ -5038,6 +5070,71 @@ public abstract class BatteryStats implements Parcelable {
|
||||
pw.println(sb.toString());
|
||||
}
|
||||
|
||||
final int numDisplays = getDisplayCount();
|
||||
if (numDisplays > 1) {
|
||||
pw.println("");
|
||||
pw.print(prefix);
|
||||
sb.setLength(0);
|
||||
sb.append(prefix);
|
||||
sb.append(" MULTI-DISPLAY POWER SUMMARY START");
|
||||
pw.println(sb.toString());
|
||||
|
||||
for (int display = 0; display < numDisplays; display++) {
|
||||
sb.setLength(0);
|
||||
sb.append(prefix);
|
||||
sb.append(" Display ");
|
||||
sb.append(display);
|
||||
sb.append(" Statistics:");
|
||||
pw.println(sb.toString());
|
||||
|
||||
final long displayScreenOnTime = getDisplayScreenOnTime(display, rawRealtime);
|
||||
sb.setLength(0);
|
||||
sb.append(prefix);
|
||||
sb.append(" Screen on: ");
|
||||
formatTimeMs(sb, displayScreenOnTime / 1000);
|
||||
sb.append("(");
|
||||
sb.append(formatRatioLocked(displayScreenOnTime, whichBatteryRealtime));
|
||||
sb.append(") ");
|
||||
pw.println(sb.toString());
|
||||
|
||||
sb.setLength(0);
|
||||
sb.append(" Screen brightness levels:");
|
||||
didOne = false;
|
||||
for (int bin = 0; bin < NUM_SCREEN_BRIGHTNESS_BINS; bin++) {
|
||||
final long timeUs = getDisplayScreenBrightnessTime(display, bin, rawRealtime);
|
||||
if (timeUs == 0) {
|
||||
continue;
|
||||
}
|
||||
didOne = true;
|
||||
sb.append("\n ");
|
||||
sb.append(prefix);
|
||||
sb.append(SCREEN_BRIGHTNESS_NAMES[bin]);
|
||||
sb.append(" ");
|
||||
formatTimeMs(sb, timeUs / 1000);
|
||||
sb.append("(");
|
||||
sb.append(formatRatioLocked(timeUs, displayScreenOnTime));
|
||||
sb.append(")");
|
||||
}
|
||||
if (!didOne) sb.append(" (no activity)");
|
||||
pw.println(sb.toString());
|
||||
|
||||
final long displayScreenDozeTimeUs = getDisplayScreenDozeTime(display, rawRealtime);
|
||||
sb.setLength(0);
|
||||
sb.append(prefix);
|
||||
sb.append(" Screen Doze: ");
|
||||
formatTimeMs(sb, displayScreenDozeTimeUs / 1000);
|
||||
sb.append("(");
|
||||
sb.append(formatRatioLocked(displayScreenDozeTimeUs, whichBatteryRealtime));
|
||||
sb.append(") ");
|
||||
pw.println(sb.toString());
|
||||
}
|
||||
pw.print(prefix);
|
||||
sb.setLength(0);
|
||||
sb.append(prefix);
|
||||
sb.append(" MULTI-DISPLAY POWER SUMMARY END");
|
||||
pw.println(sb.toString());
|
||||
}
|
||||
|
||||
pw.println("");
|
||||
pw.print(prefix);
|
||||
sb.setLength(0);
|
||||
|
||||
@@ -690,7 +690,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
* Schedule a sync because of a screen state change.
|
||||
*/
|
||||
Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery,
|
||||
boolean onBatteryScreenOff, int screenState);
|
||||
boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates);
|
||||
Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis);
|
||||
void cancelCpuSyncDueToWakelockChange();
|
||||
Future<?> scheduleSyncDueToBatteryLevelChange(long delayMillis);
|
||||
@@ -851,17 +851,84 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
public boolean mRecordAllHistory;
|
||||
boolean mNoAutoReset;
|
||||
|
||||
/**
|
||||
* Overall screen state. For multidisplay devices, this represents the current highest screen
|
||||
* state of the displays.
|
||||
*/
|
||||
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
|
||||
protected int mScreenState = Display.STATE_UNKNOWN;
|
||||
/**
|
||||
* Overall screen on timer. For multidisplay devices, this represents the time spent with at
|
||||
* least one display in the screen on state.
|
||||
*/
|
||||
StopwatchTimer mScreenOnTimer;
|
||||
/**
|
||||
* Overall screen doze timer. For multidisplay devices, this represents the time spent with
|
||||
* screen doze being the highest screen state.
|
||||
*/
|
||||
StopwatchTimer mScreenDozeTimer;
|
||||
|
||||
/**
|
||||
* Overall screen brightness bin. For multidisplay devices, this represents the current
|
||||
* brightest screen.
|
||||
*/
|
||||
int mScreenBrightnessBin = -1;
|
||||
/**
|
||||
* Overall screen brightness timers. For multidisplay devices, the {@link mScreenBrightnessBin}
|
||||
* timer will be active at any given time
|
||||
*/
|
||||
final StopwatchTimer[] mScreenBrightnessTimer =
|
||||
new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
|
||||
|
||||
boolean mPretendScreenOff;
|
||||
|
||||
private static class DisplayBatteryStats {
|
||||
/**
|
||||
* Per display screen state.
|
||||
*/
|
||||
public int screenState = Display.STATE_UNKNOWN;
|
||||
/**
|
||||
* Per display screen on timers.
|
||||
*/
|
||||
public StopwatchTimer screenOnTimer;
|
||||
/**
|
||||
* Per display screen doze timers.
|
||||
*/
|
||||
public StopwatchTimer screenDozeTimer;
|
||||
/**
|
||||
* Per display screen brightness bins.
|
||||
*/
|
||||
public int screenBrightnessBin = -1;
|
||||
/**
|
||||
* Per display screen brightness timers.
|
||||
*/
|
||||
public StopwatchTimer[] screenBrightnessTimers =
|
||||
new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
|
||||
|
||||
DisplayBatteryStats(Clocks clocks, TimeBase timeBase) {
|
||||
screenOnTimer = new StopwatchTimer(clocks, null, -1, null,
|
||||
timeBase);
|
||||
screenDozeTimer = new StopwatchTimer(clocks, null, -1, null,
|
||||
timeBase);
|
||||
for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
|
||||
screenBrightnessTimers[i] = new StopwatchTimer(clocks, null, -100 - i, null,
|
||||
timeBase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset display timers.
|
||||
*/
|
||||
public void reset(long elapsedRealtimeUs) {
|
||||
screenOnTimer.reset(false, elapsedRealtimeUs);
|
||||
screenDozeTimer.reset(false, elapsedRealtimeUs);
|
||||
for (int i = 0; i < NUM_SCREEN_BRIGHTNESS_BINS; i++) {
|
||||
screenBrightnessTimers[i].reset(false, elapsedRealtimeUs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisplayBatteryStats[] mPerDisplayBatteryStats;
|
||||
|
||||
boolean mInteractive;
|
||||
StopwatchTimer mInteractiveTimer;
|
||||
|
||||
@@ -4308,8 +4375,10 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
public void setPretendScreenOff(boolean pretendScreenOff) {
|
||||
if (mPretendScreenOff != pretendScreenOff) {
|
||||
mPretendScreenOff = pretendScreenOff;
|
||||
noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON,
|
||||
mClocks.elapsedRealtime(), mClocks.uptimeMillis(), mClocks.currentTimeMillis());
|
||||
final int primaryScreenState = mPerDisplayBatteryStats[0].screenState;
|
||||
noteScreenStateLocked(0, primaryScreenState,
|
||||
mClocks.elapsedRealtime(), mClocks.uptimeMillis(),
|
||||
mClocks.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4907,29 +4976,158 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
public void noteScreenStateLocked(int state) {
|
||||
noteScreenStateLocked(state, mClocks.elapsedRealtime(), mClocks.uptimeMillis(),
|
||||
public void noteScreenStateLocked(int display, int state) {
|
||||
noteScreenStateLocked(display, state, mClocks.elapsedRealtime(), mClocks.uptimeMillis(),
|
||||
mClocks.currentTimeMillis());
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
public void noteScreenStateLocked(int state,
|
||||
public void noteScreenStateLocked(int display, int displayState,
|
||||
long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) {
|
||||
state = mPretendScreenOff ? Display.STATE_OFF : state;
|
||||
|
||||
// Battery stats relies on there being 4 states. To accommodate this, new states beyond the
|
||||
// original 4 are mapped to one of the originals.
|
||||
if (state > MAX_TRACKED_SCREEN_STATE) {
|
||||
switch (state) {
|
||||
case Display.STATE_VR:
|
||||
state = Display.STATE_ON;
|
||||
if (displayState > MAX_TRACKED_SCREEN_STATE) {
|
||||
if (Display.isOnState(displayState)) {
|
||||
displayState = Display.STATE_ON;
|
||||
} else if (Display.isDozeState(displayState)) {
|
||||
if (Display.isSuspendedState(displayState)) {
|
||||
displayState = Display.STATE_DOZE_SUSPEND;
|
||||
} else {
|
||||
displayState = Display.STATE_DOZE;
|
||||
}
|
||||
} else if (Display.isOffState(displayState)) {
|
||||
displayState = Display.STATE_OFF;
|
||||
} else {
|
||||
Slog.wtf(TAG, "Unknown screen state (not mapped): " + displayState);
|
||||
displayState = Display.STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
// As of this point, displayState should be mapped to one of:
|
||||
// - Display.STATE_ON,
|
||||
// - Display.STATE_DOZE
|
||||
// - Display.STATE_DOZE_SUSPEND
|
||||
// - Display.STATE_OFF
|
||||
// - Display.STATE_UNKNOWN
|
||||
|
||||
int state;
|
||||
int overallBin = mScreenBrightnessBin;
|
||||
int externalUpdateFlag = 0;
|
||||
boolean shouldScheduleSync = false;
|
||||
final int numDisplay = mPerDisplayBatteryStats.length;
|
||||
if (display < 0 || display >= numDisplay) {
|
||||
Slog.wtf(TAG, "Unexpected note screen state for display " + display + " (only "
|
||||
+ mPerDisplayBatteryStats.length + " displays exist...)");
|
||||
return;
|
||||
}
|
||||
final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display];
|
||||
final int oldDisplayState = displayStats.screenState;
|
||||
|
||||
if (oldDisplayState == displayState) {
|
||||
// Nothing changed
|
||||
state = mScreenState;
|
||||
} else {
|
||||
displayStats.screenState = displayState;
|
||||
|
||||
// Stop timer for previous display state.
|
||||
switch (oldDisplayState) {
|
||||
case Display.STATE_ON:
|
||||
displayStats.screenOnTimer.stopRunningLocked(elapsedRealtimeMs);
|
||||
final int bin = displayStats.screenBrightnessBin;
|
||||
if (bin >= 0) {
|
||||
displayStats.screenBrightnessTimers[bin].stopRunningLocked(
|
||||
elapsedRealtimeMs);
|
||||
}
|
||||
overallBin = evaluateOverallScreenBrightnessBinLocked();
|
||||
shouldScheduleSync = true;
|
||||
break;
|
||||
case Display.STATE_DOZE:
|
||||
// Transition from doze to doze suspend can be ignored.
|
||||
if (displayState == Display.STATE_DOZE_SUSPEND) break;
|
||||
displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs);
|
||||
shouldScheduleSync = true;
|
||||
break;
|
||||
case Display.STATE_DOZE_SUSPEND:
|
||||
// Transition from doze suspend to doze can be ignored.
|
||||
if (displayState == Display.STATE_DOZE) break;
|
||||
displayStats.screenDozeTimer.stopRunningLocked(elapsedRealtimeMs);
|
||||
shouldScheduleSync = true;
|
||||
break;
|
||||
case Display.STATE_OFF: // fallthrough
|
||||
case Display.STATE_UNKNOWN:
|
||||
// Not tracked by timers.
|
||||
break;
|
||||
default:
|
||||
Slog.wtf(TAG, "Unknown screen state (not mapped): " + state);
|
||||
Slog.wtf(TAG,
|
||||
"Attempted to stop timer for unexpected display state " + display);
|
||||
}
|
||||
|
||||
// Start timer for new display state.
|
||||
switch (displayState) {
|
||||
case Display.STATE_ON:
|
||||
displayStats.screenOnTimer.startRunningLocked(elapsedRealtimeMs);
|
||||
final int bin = displayStats.screenBrightnessBin;
|
||||
if (bin >= 0) {
|
||||
displayStats.screenBrightnessTimers[bin].startRunningLocked(
|
||||
elapsedRealtimeMs);
|
||||
}
|
||||
overallBin = evaluateOverallScreenBrightnessBinLocked();
|
||||
shouldScheduleSync = true;
|
||||
break;
|
||||
case Display.STATE_DOZE:
|
||||
// Transition from doze suspend to doze can be ignored.
|
||||
if (oldDisplayState == Display.STATE_DOZE_SUSPEND) break;
|
||||
displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs);
|
||||
shouldScheduleSync = true;
|
||||
break;
|
||||
case Display.STATE_DOZE_SUSPEND:
|
||||
// Transition from doze to doze suspend can be ignored.
|
||||
if (oldDisplayState == Display.STATE_DOZE) break;
|
||||
displayStats.screenDozeTimer.startRunningLocked(elapsedRealtimeMs);
|
||||
shouldScheduleSync = true;
|
||||
break;
|
||||
case Display.STATE_OFF: // fallthrough
|
||||
case Display.STATE_UNKNOWN:
|
||||
// Not tracked by timers.
|
||||
break;
|
||||
default:
|
||||
Slog.wtf(TAG,
|
||||
"Attempted to start timer for unexpected display state " + displayState
|
||||
+ " for display " + display);
|
||||
}
|
||||
|
||||
if (shouldScheduleSync
|
||||
&& mGlobalMeasuredEnergyStats != null
|
||||
&& mGlobalMeasuredEnergyStats.isStandardBucketSupported(
|
||||
MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON)) {
|
||||
// Display measured energy stats is available. Prepare to schedule an
|
||||
// external sync.
|
||||
externalUpdateFlag |= ExternalStatsSync.UPDATE_DISPLAY;
|
||||
}
|
||||
|
||||
// Reevaluate most important display screen state.
|
||||
state = Display.STATE_UNKNOWN;
|
||||
for (int i = 0; i < numDisplay; i++) {
|
||||
final int tempState = mPerDisplayBatteryStats[i].screenState;
|
||||
if (tempState == Display.STATE_ON
|
||||
|| state == Display.STATE_ON) {
|
||||
state = Display.STATE_ON;
|
||||
} else if (tempState == Display.STATE_DOZE
|
||||
|| state == Display.STATE_DOZE) {
|
||||
state = Display.STATE_DOZE;
|
||||
} else if (tempState == Display.STATE_DOZE_SUSPEND
|
||||
|| state == Display.STATE_DOZE_SUSPEND) {
|
||||
state = Display.STATE_DOZE_SUSPEND;
|
||||
} else if (tempState == Display.STATE_OFF
|
||||
|| state == Display.STATE_OFF) {
|
||||
state = Display.STATE_OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean batteryRunning = mOnBatteryTimeBase.isRunning();
|
||||
final boolean batteryScreenOffRunning = mOnBatteryScreenOffTimeBase.isRunning();
|
||||
|
||||
state = mPretendScreenOff ? Display.STATE_OFF : state;
|
||||
if (mScreenState != state) {
|
||||
recordDailyStatsIfNeededLocked(true, currentTimeMs);
|
||||
final int oldState = mScreenState;
|
||||
@@ -4983,11 +5181,11 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
+ Display.stateToString(state));
|
||||
addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
|
||||
}
|
||||
// TODO: (Probably overkill) Have mGlobalMeasuredEnergyStats store supported flags and
|
||||
// only update DISPLAY if it is. Currently overkill since CPU is scheduled anyway.
|
||||
final int updateFlag = ExternalStatsSync.UPDATE_CPU | ExternalStatsSync.UPDATE_DISPLAY;
|
||||
mExternalSync.scheduleSyncDueToScreenStateChange(updateFlag,
|
||||
mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning(), state);
|
||||
|
||||
// Per screen state Cpu stats needed. Prepare to schedule an external sync.
|
||||
externalUpdateFlag |= ExternalStatsSync.UPDATE_CPU;
|
||||
shouldScheduleSync = true;
|
||||
|
||||
if (Display.isOnState(state)) {
|
||||
updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state,
|
||||
uptimeMs * 1000, elapsedRealtimeMs * 1000);
|
||||
@@ -5005,33 +5203,116 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
updateDischargeScreenLevelsLocked(oldState, state);
|
||||
}
|
||||
}
|
||||
|
||||
// Changing display states might have changed the screen used to determine the overall
|
||||
// brightness.
|
||||
maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs);
|
||||
|
||||
if (shouldScheduleSync) {
|
||||
final int numDisplays = mPerDisplayBatteryStats.length;
|
||||
final int[] displayStates = new int[numDisplays];
|
||||
for (int i = 0; i < numDisplays; i++) {
|
||||
displayStates[i] = mPerDisplayBatteryStats[i].screenState;
|
||||
}
|
||||
mExternalSync.scheduleSyncDueToScreenStateChange(externalUpdateFlag,
|
||||
batteryRunning, batteryScreenOffRunning, state, displayStates);
|
||||
}
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public void noteScreenBrightnessLocked(int brightness) {
|
||||
noteScreenBrightnessLocked(brightness, mClocks.elapsedRealtime(), mClocks.uptimeMillis());
|
||||
noteScreenBrightnessLocked(0, brightness);
|
||||
}
|
||||
|
||||
public void noteScreenBrightnessLocked(int brightness, long elapsedRealtimeMs, long uptimeMs) {
|
||||
/**
|
||||
* Note screen brightness change for a display.
|
||||
*/
|
||||
public void noteScreenBrightnessLocked(int display, int brightness) {
|
||||
noteScreenBrightnessLocked(display, brightness, mClocks.elapsedRealtime(),
|
||||
mClocks.uptimeMillis());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Note screen brightness change for a display.
|
||||
*/
|
||||
public void noteScreenBrightnessLocked(int display, int brightness, long elapsedRealtimeMs,
|
||||
long uptimeMs) {
|
||||
// Bin the brightness.
|
||||
int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
|
||||
if (bin < 0) bin = 0;
|
||||
else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
|
||||
if (mScreenBrightnessBin != bin) {
|
||||
mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
|
||||
| (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
|
||||
if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
|
||||
+ Integer.toHexString(mHistoryCur.states));
|
||||
addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
|
||||
|
||||
final int overallBin;
|
||||
|
||||
final int numDisplays = mPerDisplayBatteryStats.length;
|
||||
if (display < 0 || display >= numDisplays) {
|
||||
Slog.wtf(TAG, "Unexpected note screen brightness for display " + display + " (only "
|
||||
+ mPerDisplayBatteryStats.length + " displays exist...)");
|
||||
return;
|
||||
}
|
||||
|
||||
final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display];
|
||||
final int oldBin = displayStats.screenBrightnessBin;
|
||||
if (oldBin == bin) {
|
||||
// Nothing changed
|
||||
overallBin = mScreenBrightnessBin;
|
||||
} else {
|
||||
displayStats.screenBrightnessBin = bin;
|
||||
if (displayStats.screenState == Display.STATE_ON) {
|
||||
if (oldBin >= 0) {
|
||||
displayStats.screenBrightnessTimers[oldBin].stopRunningLocked(
|
||||
elapsedRealtimeMs);
|
||||
}
|
||||
displayStats.screenBrightnessTimers[bin].startRunningLocked(
|
||||
elapsedRealtimeMs);
|
||||
}
|
||||
overallBin = evaluateOverallScreenBrightnessBinLocked();
|
||||
}
|
||||
|
||||
maybeUpdateOverallScreenBrightness(overallBin, elapsedRealtimeMs, uptimeMs);
|
||||
}
|
||||
|
||||
private int evaluateOverallScreenBrightnessBinLocked() {
|
||||
int overallBin = -1;
|
||||
final int numDisplays = getDisplayCount();
|
||||
for (int display = 0; display < numDisplays; display++) {
|
||||
final int displayBrightnessBin;
|
||||
if (mPerDisplayBatteryStats[display].screenState == Display.STATE_ON) {
|
||||
displayBrightnessBin = mPerDisplayBatteryStats[display].screenBrightnessBin;
|
||||
} else {
|
||||
displayBrightnessBin = -1;
|
||||
}
|
||||
if (displayBrightnessBin > overallBin) {
|
||||
overallBin = displayBrightnessBin;
|
||||
}
|
||||
}
|
||||
return overallBin;
|
||||
}
|
||||
|
||||
private void maybeUpdateOverallScreenBrightness(int overallBin, long elapsedRealtimeMs,
|
||||
long uptimeMs) {
|
||||
if (mScreenBrightnessBin != overallBin) {
|
||||
if (overallBin >= 0) {
|
||||
mHistoryCur.states = (mHistoryCur.states & ~HistoryItem.STATE_BRIGHTNESS_MASK)
|
||||
| (overallBin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
|
||||
if (DEBUG_HISTORY) {
|
||||
Slog.v(TAG, "Screen brightness " + overallBin + " to: "
|
||||
+ Integer.toHexString(mHistoryCur.states));
|
||||
}
|
||||
addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
|
||||
}
|
||||
if (mScreenState == Display.STATE_ON) {
|
||||
if (mScreenBrightnessBin >= 0) {
|
||||
mScreenBrightnessTimer[mScreenBrightnessBin]
|
||||
.stopRunningLocked(elapsedRealtimeMs);
|
||||
}
|
||||
mScreenBrightnessTimer[bin]
|
||||
.startRunningLocked(elapsedRealtimeMs);
|
||||
if (overallBin >= 0) {
|
||||
mScreenBrightnessTimer[overallBin]
|
||||
.startRunningLocked(elapsedRealtimeMs);
|
||||
}
|
||||
}
|
||||
mScreenBrightnessBin = bin;
|
||||
mScreenBrightnessBin = overallBin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6693,6 +6974,31 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
return mScreenBrightnessTimer[brightnessBin];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayCount() {
|
||||
return mPerDisplayBatteryStats.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDisplayScreenOnTime(int display, long elapsedRealtimeUs) {
|
||||
return mPerDisplayBatteryStats[display].screenOnTimer.getTotalTimeLocked(elapsedRealtimeUs,
|
||||
STATS_SINCE_CHARGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDisplayScreenDozeTime(int display, long elapsedRealtimeUs) {
|
||||
return mPerDisplayBatteryStats[display].screenDozeTimer.getTotalTimeLocked(
|
||||
elapsedRealtimeUs, STATS_SINCE_CHARGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDisplayScreenBrightnessTime(int display, int brightnessBin,
|
||||
long elapsedRealtimeUs) {
|
||||
final DisplayBatteryStats displayStats = mPerDisplayBatteryStats[display];
|
||||
return displayStats.screenBrightnessTimers[brightnessBin].getTotalTimeLocked(
|
||||
elapsedRealtimeUs, STATS_SINCE_CHARGED);
|
||||
}
|
||||
|
||||
@Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
|
||||
return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
|
||||
}
|
||||
@@ -10694,6 +11000,10 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null,
|
||||
mOnBatteryTimeBase);
|
||||
}
|
||||
|
||||
mPerDisplayBatteryStats = new DisplayBatteryStats[1];
|
||||
mPerDisplayBatteryStats[0] = new DisplayBatteryStats(mClocks, mOnBatteryTimeBase);
|
||||
|
||||
mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase);
|
||||
mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
|
||||
mOnBatteryTimeBase);
|
||||
@@ -10806,6 +11116,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
// Initialize the estimated battery capacity to a known preset one.
|
||||
mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity();
|
||||
}
|
||||
|
||||
setDisplayCountLocked(mPowerProfile.getNumDisplays());
|
||||
}
|
||||
|
||||
PowerProfile getPowerProfile() {
|
||||
@@ -10838,6 +11150,16 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
mExternalSync = sync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and set multi display timers and states.
|
||||
*/
|
||||
public void setDisplayCountLocked(int numDisplays) {
|
||||
mPerDisplayBatteryStats = new DisplayBatteryStats[numDisplays];
|
||||
for (int i = 0; i < numDisplays; i++) {
|
||||
mPerDisplayBatteryStats[i] = new DisplayBatteryStats(mClocks, mOnBatteryTimeBase);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateDailyDeadlineLocked() {
|
||||
// Get the current time.
|
||||
long currentTimeMs = mDailyStartTimeMs = mClocks.currentTimeMillis();
|
||||
@@ -11314,6 +11636,11 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs);
|
||||
}
|
||||
|
||||
final int numDisplays = mPerDisplayBatteryStats.length;
|
||||
for (int i = 0; i < numDisplays; i++) {
|
||||
mPerDisplayBatteryStats[i].reset(elapsedRealtimeUs);
|
||||
}
|
||||
|
||||
if (mPowerProfile != null) {
|
||||
mEstimatedBatteryCapacityMah = (int) mPowerProfile.getBatteryCapacity();
|
||||
} else {
|
||||
|
||||
@@ -47,13 +47,13 @@ public class AmbientDisplayPowerCalculatorTest {
|
||||
|
||||
stats.updateDisplayMeasuredEnergyStatsLocked(300_000_000, Display.STATE_ON, 0);
|
||||
|
||||
stats.noteScreenStateLocked(Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS,
|
||||
stats.noteScreenStateLocked(0, Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS,
|
||||
30 * MINUTE_IN_MS);
|
||||
|
||||
stats.updateDisplayMeasuredEnergyStatsLocked(200_000_000, Display.STATE_DOZE,
|
||||
30 * MINUTE_IN_MS);
|
||||
|
||||
stats.noteScreenStateLocked(Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS,
|
||||
stats.noteScreenStateLocked(0, Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS,
|
||||
120 * MINUTE_IN_MS);
|
||||
|
||||
stats.updateDisplayMeasuredEnergyStatsLocked(100_000_000, Display.STATE_OFF,
|
||||
@@ -78,9 +78,9 @@ public class AmbientDisplayPowerCalculatorTest {
|
||||
public void testPowerProfileBasedModel() {
|
||||
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
|
||||
|
||||
stats.noteScreenStateLocked(Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS,
|
||||
stats.noteScreenStateLocked(0, Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS,
|
||||
30 * MINUTE_IN_MS);
|
||||
stats.noteScreenStateLocked(Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS,
|
||||
stats.noteScreenStateLocked(0, Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS,
|
||||
120 * MINUTE_IN_MS);
|
||||
|
||||
AmbientDisplayPowerCalculator calculator =
|
||||
|
||||
@@ -16,9 +16,13 @@
|
||||
|
||||
package com.android.internal.os;
|
||||
|
||||
import static android.os.BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
|
||||
import static android.os.BatteryStats.STATS_SINCE_CHARGED;
|
||||
import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;
|
||||
|
||||
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
|
||||
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStats.HistoryItem;
|
||||
@@ -37,8 +41,10 @@ import com.android.internal.power.MeasuredEnergyStats;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
/**
|
||||
* Test various BatteryStatsImpl noteStart methods.
|
||||
@@ -317,18 +323,130 @@ public class BatteryStatsNoteTest extends TestCase {
|
||||
public void testNoteScreenStateLocked() throws Exception {
|
||||
final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
|
||||
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"});
|
||||
|
||||
bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
|
||||
bi.noteScreenStateLocked(Display.STATE_ON);
|
||||
bi.noteScreenStateLocked(Display.STATE_DOZE);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(bi.getScreenState(), Display.STATE_DOZE);
|
||||
bi.noteScreenStateLocked(Display.STATE_ON);
|
||||
assertEquals(Display.STATE_DOZE, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(bi.getScreenState(), Display.STATE_ON);
|
||||
bi.noteScreenStateLocked(Display.STATE_OFF);
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(bi.getScreenState(), Display.STATE_OFF);
|
||||
assertEquals(Display.STATE_OFF, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
// STATE_VR note should map to STATE_ON.
|
||||
bi.noteScreenStateLocked(0, Display.STATE_VR);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
// STATE_ON_SUSPEND note should map to STATE_ON.
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
// Transition from ON to ON state should not cause an External Sync
|
||||
assertEquals(0, bi.getAndClearExternalStatsSyncFlags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly for
|
||||
* multi display devices
|
||||
*/
|
||||
@SmallTest
|
||||
public void testNoteScreenStateLocked_multiDisplay() throws Exception {
|
||||
final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
|
||||
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
bi.setDisplayCountLocked(2);
|
||||
bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"});
|
||||
|
||||
bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
bi.noteScreenStateLocked(1, Display.STATE_OFF);
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_DOZE, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_OFF, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
// STATE_VR note should map to STATE_ON.
|
||||
bi.noteScreenStateLocked(0, Display.STATE_VR);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
// STATE_ON_SUSPEND note should map to STATE_ON.
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
// Transition from ON to ON state should not cause an External Sync
|
||||
assertEquals(0, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(1, Display.STATE_DOZE);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
// Should remain STATE_ON since display0 is still on.
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
// Overall screen state did not change, so no need to sync CPU stats.
|
||||
assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_DOZE, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_DOZE, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND);
|
||||
assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_DOZE, bi.getScreenState());
|
||||
// Overall screen state did not change, so no need to sync CPU stats.
|
||||
assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_VR);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
|
||||
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND);
|
||||
assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
|
||||
assertEquals(Display.STATE_ON, bi.getScreenState());
|
||||
assertEquals(0, bi.getAndClearExternalStatsSyncFlags());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -352,32 +470,317 @@ public class BatteryStatsNoteTest extends TestCase {
|
||||
bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000);
|
||||
// Turn on display at 200us
|
||||
clocks.realtime = clocks.uptime = 200;
|
||||
bi.noteScreenStateLocked(Display.STATE_ON);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 310;
|
||||
bi.noteScreenStateLocked(Display.STATE_OFF);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 400;
|
||||
bi.noteScreenStateLocked(Display.STATE_DOZE);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000));
|
||||
assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 1000;
|
||||
bi.noteScreenStateLocked(Display.STATE_OFF);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1290_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(600_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1500_000));
|
||||
assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1500_000));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly for multi display
|
||||
* devices.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testNoteScreenStateTimersLocked_multiDisplay() throws Exception {
|
||||
final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
|
||||
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
bi.setDisplayCountLocked(2);
|
||||
|
||||
clocks.realtime = clocks.uptime = 100;
|
||||
// Device startup, setOnBatteryLocked calls updateTimebases
|
||||
bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000);
|
||||
// Turn on display at 200us
|
||||
clocks.realtime = clocks.uptime = 200;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
bi.noteScreenStateLocked(1, Display.STATE_OFF);
|
||||
assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 250_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(1, 250_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 310;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 350_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(1, 350_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 400;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000));
|
||||
assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 500_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(1, 500_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 1000;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertEquals(1000_000, bi.computeBatteryRealtime(1100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(890_000, bi.computeBatteryScreenOffRealtime(1100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getScreenOnTime(1100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(600_000, bi.getScreenDozeTime(1100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1100_000));
|
||||
assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1100_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 1100_000));
|
||||
assertEquals(0, bi.getDisplayScreenDozeTime(1, 1100_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 1200;
|
||||
// Change state of second display to doze
|
||||
bi.noteScreenStateLocked(1, Display.STATE_DOZE);
|
||||
assertEquals(1150_000, bi.computeBatteryRealtime(1250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1040_000, bi.computeBatteryScreenOffRealtime(1250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getScreenOnTime(1250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(650_000, bi.getScreenDozeTime(1250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1250_000));
|
||||
assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1250_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 1250_000));
|
||||
assertEquals(50_000, bi.getDisplayScreenDozeTime(1, 1250_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 1310;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
assertEquals(1250_000, bi.computeBatteryRealtime(1350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1100_000, bi.computeBatteryScreenOffRealtime(1350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(150_000, bi.getScreenOnTime(1350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(710_000, bi.getScreenDozeTime(1350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(150_000, bi.getDisplayScreenOnTime(0, 1350_000));
|
||||
assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1350_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 1350_000));
|
||||
assertEquals(150_000, bi.getDisplayScreenDozeTime(1, 1350_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 1400;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1200_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(200_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(810_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(200_000, bi.getDisplayScreenOnTime(0, 1500_000));
|
||||
assertEquals(700_000, bi.getDisplayScreenDozeTime(0, 1500_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 1500_000));
|
||||
assertEquals(300_000, bi.getDisplayScreenDozeTime(1, 1500_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 2000;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertEquals(2000_000, bi.computeBatteryRealtime(2100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1800_000, bi.computeBatteryScreenOffRealtime(2100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(200_000, bi.getScreenOnTime(2100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1410_000, bi.getScreenDozeTime(2100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2100_000));
|
||||
assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2100_000));
|
||||
assertEquals(0, bi.getDisplayScreenOnTime(1, 2100_000));
|
||||
assertEquals(900_000, bi.getDisplayScreenDozeTime(1, 2100_000));
|
||||
|
||||
|
||||
clocks.realtime = clocks.uptime = 2200;
|
||||
// Change state of second display to on
|
||||
bi.noteScreenStateLocked(1, Display.STATE_ON);
|
||||
assertEquals(2150_000, bi.computeBatteryRealtime(2250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(250_000, bi.getScreenOnTime(2250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1510_000, bi.getScreenDozeTime(2250_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2250_000));
|
||||
assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2250_000));
|
||||
assertEquals(50_000, bi.getDisplayScreenOnTime(1, 2250_000));
|
||||
assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2250_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 2310;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
assertEquals(2250_000, bi.computeBatteryRealtime(2350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(350_000, bi.getScreenOnTime(2350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1510_000, bi.getScreenDozeTime(2350_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(240_000, bi.getDisplayScreenOnTime(0, 2350_000));
|
||||
assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2350_000));
|
||||
assertEquals(150_000, bi.getDisplayScreenOnTime(1, 2350_000));
|
||||
assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2350_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 2400;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
assertEquals(2400_000, bi.computeBatteryRealtime(2500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(500_000, bi.getScreenOnTime(2500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1510_000, bi.getScreenDozeTime(2500_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(290_000, bi.getDisplayScreenOnTime(0, 2500_000));
|
||||
assertEquals(1300_000, bi.getDisplayScreenDozeTime(0, 2500_000));
|
||||
assertEquals(300_000, bi.getDisplayScreenOnTime(1, 2500_000));
|
||||
assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2500_000));
|
||||
|
||||
clocks.realtime = clocks.uptime = 3000;
|
||||
bi.noteScreenStateLocked(0, Display.STATE_OFF);
|
||||
assertEquals(3000_000, bi.computeBatteryRealtime(3100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(3100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1100_000, bi.getScreenOnTime(3100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(1510_000, bi.getScreenDozeTime(3100_000, STATS_SINCE_CHARGED));
|
||||
assertEquals(290_000, bi.getDisplayScreenOnTime(0, 3100_000));
|
||||
assertEquals(1800_000, bi.getDisplayScreenDozeTime(0, 3100_000));
|
||||
assertEquals(900_000, bi.getDisplayScreenOnTime(1, 3100_000));
|
||||
assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 3100_000));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test BatteryStatsImpl.noteScreenBrightnessLocked updates timers correctly.
|
||||
*/
|
||||
@SmallTest
|
||||
public void testScreenBrightnessLocked_multiDisplay() throws Exception {
|
||||
final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
|
||||
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
|
||||
|
||||
final int numDisplay = 2;
|
||||
bi.setDisplayCountLocked(numDisplay);
|
||||
|
||||
|
||||
final long[] overallExpected = new long[NUM_SCREEN_BRIGHTNESS_BINS];
|
||||
final long[][] perDisplayExpected = new long[numDisplay][NUM_SCREEN_BRIGHTNESS_BINS];
|
||||
class Bookkeeper {
|
||||
public long currentTimeMs = 100;
|
||||
public int overallActiveBin = -1;
|
||||
public int[] perDisplayActiveBin = new int[numDisplay];
|
||||
}
|
||||
final Bookkeeper bk = new Bookkeeper();
|
||||
Arrays.fill(bk.perDisplayActiveBin, -1);
|
||||
|
||||
IntConsumer incrementTime = inc -> {
|
||||
bk.currentTimeMs += inc;
|
||||
if (bk.overallActiveBin >= 0) {
|
||||
overallExpected[bk.overallActiveBin] += inc;
|
||||
}
|
||||
for (int i = 0; i < numDisplay; i++) {
|
||||
final int bin = bk.perDisplayActiveBin[i];
|
||||
if (bin >= 0) {
|
||||
perDisplayExpected[i][bin] += inc;
|
||||
}
|
||||
}
|
||||
clocks.realtime = clocks.uptime = bk.currentTimeMs;
|
||||
};
|
||||
|
||||
bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
bi.noteScreenStateLocked(1, Display.STATE_ON);
|
||||
|
||||
incrementTime.accept(100);
|
||||
bi.noteScreenBrightnessLocked(0, 25);
|
||||
bi.noteScreenBrightnessLocked(1, 25);
|
||||
// floor(25/256*5) = bin 0
|
||||
bk.overallActiveBin = 0;
|
||||
bk.perDisplayActiveBin[0] = 0;
|
||||
bk.perDisplayActiveBin[1] = 0;
|
||||
|
||||
incrementTime.accept(50);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(13);
|
||||
bi.noteScreenBrightnessLocked(0, 100);
|
||||
// floor(25/256*5) = bin 1
|
||||
bk.overallActiveBin = 1;
|
||||
bk.perDisplayActiveBin[0] = 1;
|
||||
|
||||
incrementTime.accept(44);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(22);
|
||||
bi.noteScreenBrightnessLocked(1, 200);
|
||||
// floor(200/256*5) = bin 3
|
||||
bk.overallActiveBin = 3;
|
||||
bk.perDisplayActiveBin[1] = 3;
|
||||
|
||||
incrementTime.accept(33);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(77);
|
||||
bi.noteScreenBrightnessLocked(0, 150);
|
||||
// floor(150/256*5) = bin 2
|
||||
// Overall active bin should not change
|
||||
bk.perDisplayActiveBin[0] = 2;
|
||||
|
||||
incrementTime.accept(88);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(11);
|
||||
bi.noteScreenStateLocked(1, Display.STATE_OFF);
|
||||
// Display 1 should timers should stop incrementing
|
||||
// Overall active bin should fallback to display 0's bin
|
||||
bk.overallActiveBin = 2;
|
||||
bk.perDisplayActiveBin[1] = -1;
|
||||
|
||||
incrementTime.accept(99);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(200);
|
||||
bi.noteScreenBrightnessLocked(0, 255);
|
||||
// floor(150/256*5) = bin 4
|
||||
bk.overallActiveBin = 4;
|
||||
bk.perDisplayActiveBin[0] = 4;
|
||||
|
||||
incrementTime.accept(300);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(200);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_DOZE);
|
||||
// No displays are on. No brightness timers should be active.
|
||||
bk.overallActiveBin = -1;
|
||||
bk.perDisplayActiveBin[0] = -1;
|
||||
|
||||
incrementTime.accept(300);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(400);
|
||||
bi.noteScreenStateLocked(1, Display.STATE_ON);
|
||||
// Display 1 turned back on.
|
||||
bk.overallActiveBin = 3;
|
||||
bk.perDisplayActiveBin[1] = 3;
|
||||
|
||||
incrementTime.accept(500);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
|
||||
incrementTime.accept(600);
|
||||
bi.noteScreenStateLocked(0, Display.STATE_ON);
|
||||
// Display 0 turned back on.
|
||||
bk.overallActiveBin = 4;
|
||||
bk.perDisplayActiveBin[0] = 4;
|
||||
|
||||
incrementTime.accept(700);
|
||||
checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
@@ -822,4 +1225,19 @@ public class BatteryStatsNoteTest extends TestCase {
|
||||
|
||||
assertEquals("Wrong uid2 blame in bucket 1 for Case " + caseName, blame2B, actualUid2[1]);
|
||||
}
|
||||
|
||||
private void checkScreenBrightnesses(long[] overallExpected, long[][] perDisplayExpected,
|
||||
BatteryStatsImpl bi, long currentTimeMs) {
|
||||
final int numDisplay = bi.getDisplayCount();
|
||||
for (int bin = 0; bin < NUM_SCREEN_BRIGHTNESS_BINS; bin++) {
|
||||
for (int display = 0; display < numDisplay; display++) {
|
||||
assertEquals("Failure for display " + display + " screen brightness bin " + bin,
|
||||
perDisplayExpected[display][bin] * 1000,
|
||||
bi.getDisplayScreenBrightnessTime(display, bin, currentTimeMs * 1000));
|
||||
}
|
||||
assertEquals("Failure for overall screen brightness bin " + bin,
|
||||
overallExpected[bin] * 1000,
|
||||
bi.getScreenBrightnessTime(bin, currentTimeMs * 1000, STATS_SINCE_CHARGED));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +39,14 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
|
||||
public BatteryStatsImpl.Clocks clocks;
|
||||
public boolean mForceOnBattery;
|
||||
private NetworkStats mNetworkStats;
|
||||
private DummyExternalStatsSync mExternalStatsSync = new DummyExternalStatsSync();
|
||||
|
||||
MockBatteryStatsImpl(Clocks clocks) {
|
||||
super(clocks);
|
||||
this.clocks = mClocks;
|
||||
initTimersAndCounters();
|
||||
|
||||
setExternalStatsSyncLocked(new DummyExternalStatsSync());
|
||||
setExternalStatsSyncLocked(mExternalStatsSync);
|
||||
informThatAllExternalStatsAreFlushed();
|
||||
|
||||
// A no-op handler.
|
||||
@@ -182,7 +183,15 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
|
||||
return mPendingUids;
|
||||
}
|
||||
|
||||
public int getAndClearExternalStatsSyncFlags() {
|
||||
final int flags = mExternalStatsSync.flags;
|
||||
mExternalStatsSync.flags = 0;
|
||||
return flags;
|
||||
}
|
||||
|
||||
private class DummyExternalStatsSync implements ExternalStatsSync {
|
||||
public int flags = 0;
|
||||
|
||||
@Override
|
||||
public Future<?> scheduleSync(String reason, int flags) {
|
||||
return null;
|
||||
@@ -211,8 +220,9 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> scheduleSyncDueToScreenStateChange(
|
||||
int flag, boolean onBattery, boolean onBatteryScreenOff, int screenState) {
|
||||
public Future<?> scheduleSyncDueToScreenStateChange(int flag, boolean onBattery,
|
||||
boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates) {
|
||||
flags |= flag;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ScreenPowerCalculatorTest {
|
||||
mStatsRule.initMeasuredEnergyStatsLocked();
|
||||
BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
|
||||
|
||||
batteryStats.noteScreenStateLocked(Display.STATE_ON, 0, 0, 0);
|
||||
batteryStats.noteScreenStateLocked(0, Display.STATE_ON, 0, 0, 0);
|
||||
batteryStats.updateDisplayMeasuredEnergyStatsLocked(0, Display.STATE_ON, 0);
|
||||
setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true,
|
||||
0, 0);
|
||||
@@ -70,7 +70,7 @@ public class ScreenPowerCalculatorTest {
|
||||
batteryStats.updateDisplayMeasuredEnergyStatsLocked(300_000_000, Display.STATE_ON,
|
||||
60 * MINUTE_IN_MS);
|
||||
|
||||
batteryStats.noteScreenStateLocked(Display.STATE_OFF,
|
||||
batteryStats.noteScreenStateLocked(0, Display.STATE_OFF,
|
||||
80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
|
||||
setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, false,
|
||||
80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
|
||||
@@ -133,20 +133,20 @@ public class ScreenPowerCalculatorTest {
|
||||
public void testPowerProfileBasedModel() {
|
||||
BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
|
||||
|
||||
batteryStats.noteScreenStateLocked(Display.STATE_ON, 0, 0, 0);
|
||||
batteryStats.noteScreenBrightnessLocked(255, 0, 0);
|
||||
batteryStats.noteScreenStateLocked(0, Display.STATE_ON, 0, 0, 0);
|
||||
batteryStats.noteScreenBrightnessLocked(0, 255, 0, 0);
|
||||
setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true,
|
||||
0, 0);
|
||||
|
||||
batteryStats.noteScreenBrightnessLocked(100, 5 * MINUTE_IN_MS, 5 * MINUTE_IN_MS);
|
||||
batteryStats.noteScreenBrightnessLocked(200, 10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
|
||||
batteryStats.noteScreenBrightnessLocked(0, 100, 5 * MINUTE_IN_MS, 5 * MINUTE_IN_MS);
|
||||
batteryStats.noteScreenBrightnessLocked(0, 200, 10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
|
||||
|
||||
setProcState(APP_UID1, ActivityManager.PROCESS_STATE_CACHED_EMPTY, false,
|
||||
20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
|
||||
setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP, true,
|
||||
20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS);
|
||||
|
||||
batteryStats.noteScreenStateLocked(Display.STATE_OFF,
|
||||
batteryStats.noteScreenStateLocked(0, Display.STATE_OFF,
|
||||
80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
|
||||
setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, false,
|
||||
80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
|
||||
|
||||
@@ -113,6 +113,9 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
@GuardedBy("this")
|
||||
private int mScreenState;
|
||||
|
||||
@GuardedBy("this")
|
||||
private int[] mPerDisplayScreenStates = null;
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean mUseLatestStates = true;
|
||||
|
||||
@@ -291,8 +294,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> scheduleSyncDueToScreenStateChange(
|
||||
int flags, boolean onBattery, boolean onBatteryScreenOff, int screenState) {
|
||||
public Future<?> scheduleSyncDueToScreenStateChange(int flags, boolean onBattery,
|
||||
boolean onBatteryScreenOff, int screenState, int[] perDisplayScreenStates) {
|
||||
synchronized (BatteryExternalStatsWorker.this) {
|
||||
if (mCurrentFuture == null || (mUpdateFlags & UPDATE_CPU) == 0) {
|
||||
mOnBattery = onBattery;
|
||||
@@ -301,6 +304,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
}
|
||||
// always update screen state
|
||||
mScreenState = screenState;
|
||||
mPerDisplayScreenStates = perDisplayScreenStates;
|
||||
return scheduleSyncLocked("screen-state", flags);
|
||||
}
|
||||
}
|
||||
@@ -432,6 +436,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
final boolean onBattery;
|
||||
final boolean onBatteryScreenOff;
|
||||
final int screenState;
|
||||
final int[] displayScreenStates;
|
||||
final boolean useLatestStates;
|
||||
synchronized (BatteryExternalStatsWorker.this) {
|
||||
updateFlags = mUpdateFlags;
|
||||
@@ -440,6 +445,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
onBattery = mOnBattery;
|
||||
onBatteryScreenOff = mOnBatteryScreenOff;
|
||||
screenState = mScreenState;
|
||||
displayScreenStates = mPerDisplayScreenStates;
|
||||
useLatestStates = mUseLatestStates;
|
||||
mUpdateFlags = 0;
|
||||
mCurrentReason = null;
|
||||
@@ -461,7 +467,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
}
|
||||
try {
|
||||
updateExternalStatsLocked(reason, updateFlags, onBattery,
|
||||
onBatteryScreenOff, screenState, useLatestStates);
|
||||
onBatteryScreenOff, screenState, displayScreenStates,
|
||||
useLatestStates);
|
||||
} finally {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "end updateExternalStatsSync");
|
||||
@@ -506,7 +513,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
|
||||
@GuardedBy("mWorkerLock")
|
||||
private void updateExternalStatsLocked(final String reason, int updateFlags, boolean onBattery,
|
||||
boolean onBatteryScreenOff, int screenState, boolean useLatestStates) {
|
||||
boolean onBatteryScreenOff, int screenState, int[] displayScreenStates,
|
||||
boolean useLatestStates) {
|
||||
// We will request data from external processes asynchronously, and wait on a timeout.
|
||||
SynchronousResultReceiver wifiReceiver = null;
|
||||
SynchronousResultReceiver bluetoothReceiver = null;
|
||||
@@ -661,7 +669,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
|
||||
if (measuredEnergyDeltas != null) {
|
||||
final long[] displayChargeUC = measuredEnergyDeltas.displayChargeUC;
|
||||
if (displayChargeUC != null && displayChargeUC.length > 0) {
|
||||
// TODO (b/194107383): pass all display ordinals to mStats.
|
||||
// TODO (b/194107383): pass all display ordinals to mStats with
|
||||
// displayScreenStates
|
||||
final long primaryDisplayChargeUC = displayChargeUC[0];
|
||||
// If updating, pass in what BatteryExternalStatsWorker thinks screenState is.
|
||||
mStats.updateDisplayMeasuredEnergyStatsLocked(primaryDisplayChargeUC,
|
||||
|
||||
@@ -1215,7 +1215,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
mHandler.post(() -> {
|
||||
if (DBG) Slog.d(TAG, "begin noteScreenState");
|
||||
synchronized (mStats) {
|
||||
mStats.noteScreenStateLocked(state, elapsedRealtime, uptime, currentTime);
|
||||
mStats.noteScreenStateLocked(0, state, elapsedRealtime, uptime, currentTime);
|
||||
}
|
||||
if (DBG) Slog.d(TAG, "end noteScreenState");
|
||||
});
|
||||
@@ -1230,7 +1230,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
final long uptime = SystemClock.uptimeMillis();
|
||||
mHandler.post(() -> {
|
||||
synchronized (mStats) {
|
||||
mStats.noteScreenBrightnessLocked(brightness, elapsedRealtime, uptime);
|
||||
mStats.noteScreenBrightnessLocked(0, brightness, elapsedRealtime, uptime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ public class BatteryExternalStatsWorkerTest {
|
||||
public class TestBatteryStatsImpl extends BatteryStatsImpl {
|
||||
public TestBatteryStatsImpl(Context context) {
|
||||
mPowerProfile = new PowerProfile(context, true /* forTest */);
|
||||
initTimersAndCounters();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user