Merge "Power Monitor Addition framworks base:"

This commit is contained in:
Blake Kragten
2019-02-14 19:33:34 +00:00
committed by Android (Google) Code Review
8 changed files with 499 additions and 62 deletions

View File

@@ -46,6 +46,7 @@ import com.android.internal.os.BatteryStatsHelper;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -262,6 +263,7 @@ public abstract class BatteryStats implements Parcelable {
private static final long BYTES_PER_KB = 1024;
private static final long BYTES_PER_MB = 1048576; // 1024^2
private static final long BYTES_PER_GB = 1073741824; //1024^3
public static final double MILLISECONDS_IN_HOUR = 3600 * 1000;
private static final String VERSION_DATA = "vers";
private static final String UID_DATA = "uid";
@@ -482,6 +484,13 @@ public abstract class BatteryStats implements Parcelable {
* yield a value of 0 if the device doesn't support power calculations.
*/
public abstract LongCounter getPowerCounter();
/**
* @return a non-null {@link LongCounter} representing total power monitored on the rails
* in mAms (miliamps-milliseconds). The counter may always yield a value of 0 if the device
* doesn't support power rail monitoring.
*/
public abstract LongCounter getMonitoredRailChargeConsumedMaMs();
}
/**
@@ -1526,6 +1535,9 @@ public abstract class BatteryStats implements Parcelable {
// The charge of the battery in micro-Ampere-hours.
public int batteryChargeUAh;
public double modemRailChargeMah;
public double wifiRailChargeMah;
// Constants from SCREEN_BRIGHTNESS_*
public static final int STATE_BRIGHTNESS_SHIFT = 0;
public static final int STATE_BRIGHTNESS_MASK = 0x7;
@@ -1738,6 +1750,8 @@ public abstract class BatteryStats implements Parcelable {
| ((((int)batteryVoltage)<<16)&0xffff0000);
dest.writeInt(bat);
dest.writeInt(batteryChargeUAh);
dest.writeDouble(modemRailChargeMah);
dest.writeDouble(wifiRailChargeMah);
dest.writeInt(states);
dest.writeInt(states2);
if (wakelockTag != null) {
@@ -1767,6 +1781,8 @@ public abstract class BatteryStats implements Parcelable {
batteryTemperature = (short)(bat2&0xffff);
batteryVoltage = (char)((bat2>>16)&0xffff);
batteryChargeUAh = src.readInt();
modemRailChargeMah = src.readDouble();
wifiRailChargeMah = src.readDouble();
states = src.readInt();
states2 = src.readInt();
if ((bat&0x10000000) != 0) {
@@ -1807,6 +1823,8 @@ public abstract class BatteryStats implements Parcelable {
batteryTemperature = 0;
batteryVoltage = 0;
batteryChargeUAh = 0;
modemRailChargeMah = 0;
wifiRailChargeMah = 0;
states = 0;
states2 = 0;
wakelockTag = null;
@@ -1835,6 +1853,8 @@ public abstract class BatteryStats implements Parcelable {
batteryTemperature = o.batteryTemperature;
batteryVoltage = o.batteryVoltage;
batteryChargeUAh = o.batteryChargeUAh;
modemRailChargeMah = o.modemRailChargeMah;
wifiRailChargeMah = o.wifiRailChargeMah;
states = o.states;
states2 = o.states2;
if (o.wakelockTag != null) {
@@ -1867,6 +1887,8 @@ public abstract class BatteryStats implements Parcelable {
&& batteryTemperature == o.batteryTemperature
&& batteryVoltage == o.batteryVoltage
&& batteryChargeUAh == o.batteryChargeUAh
&& modemRailChargeMah == o.modemRailChargeMah
&& wifiRailChargeMah == o.wifiRailChargeMah
&& states == o.states
&& states2 == o.states2
&& currentTime == o.currentTime;
@@ -3311,7 +3333,8 @@ public abstract class BatteryStats implements Parcelable {
if (counter.getIdleTimeCounter().getCountLocked(which) != 0
|| counter.getRxTimeCounter().getCountLocked(which) != 0
|| counter.getPowerCounter().getCountLocked(which) != 0) {
|| counter.getPowerCounter().getCountLocked(which) != 0
|| counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which) != 0) {
return true;
}
@@ -3345,7 +3368,10 @@ public abstract class BatteryStats implements Parcelable {
pw.print(",");
pw.print(counter.getRxTimeCounter().getCountLocked(which));
pw.print(",");
pw.print(counter.getPowerCounter().getCountLocked(which) / (1000 * 60 * 60));
pw.print(counter.getPowerCounter().getCountLocked(which) / (MILLISECONDS_IN_HOUR));
pw.print(",");
pw.print(counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which)
/ (MILLISECONDS_IN_HOUR));
for (LongCounter c : counter.getTxTimeCounters()) {
pw.print(",");
pw.print(c.getCountLocked(which));
@@ -3370,7 +3396,10 @@ public abstract class BatteryStats implements Parcelable {
proto.write(ControllerActivityProto.RX_DURATION_MS,
counter.getRxTimeCounter().getCountLocked(which));
proto.write(ControllerActivityProto.POWER_MAH,
counter.getPowerCounter().getCountLocked(which) / (1000 * 60 * 60));
counter.getPowerCounter().getCountLocked(which) / (MILLISECONDS_IN_HOUR));
proto.write(ControllerActivityProto.MONITORED_RAIL_CHARGE_MAH,
counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which)
/ (MILLISECONDS_IN_HOUR));
long tToken;
LongCounter[] txCounters = counter.getTxTimeCounters();
@@ -3400,6 +3429,8 @@ public abstract class BatteryStats implements Parcelable {
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
final long powerDrainMaMs = counter.getPowerCounter().getCountLocked(which);
final long monitoredRailChargeConsumedMaMs =
counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which);
// Battery real time
final long totalControllerActivityTimeMs
= computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
@@ -3522,10 +3553,22 @@ public abstract class BatteryStats implements Parcelable {
sb.append(" ");
sb.append(controllerName);
sb.append(" Battery drain: ").append(
BatteryStatsHelper.makemAh(powerDrainMaMs / (double) (1000*60*60)));
BatteryStatsHelper.makemAh(powerDrainMaMs / MILLISECONDS_IN_HOUR));
sb.append("mAh");
pw.println(sb.toString());
}
if (monitoredRailChargeConsumedMaMs > 0) {
sb.setLength(0);
sb.append(prefix);
sb.append(" ");
sb.append(controllerName);
sb.append(" Monitored rail energy drain: ").append(
new DecimalFormat("#.##").format(
monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR));
sb.append(" mAh");
pw.println(sb.toString());
}
}
/**
@@ -6103,6 +6146,8 @@ public abstract class BatteryStats implements Parcelable {
int oldTemp = -1;
int oldVolt = -1;
int oldChargeMAh = -1;
double oldModemRailChargeMah = -1;
double oldWifiRailChargeMah = -1;
long lastTime = -1;
void reset() {
@@ -6114,6 +6159,8 @@ public abstract class BatteryStats implements Parcelable {
oldTemp = -1;
oldVolt = -1;
oldChargeMAh = -1;
oldModemRailChargeMah = -1;
oldWifiRailChargeMah = -1;
}
public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
@@ -6299,6 +6346,16 @@ public abstract class BatteryStats implements Parcelable {
item.append(checkin ? ",Bcc=" : " charge=");
item.append(oldChargeMAh);
}
if (oldModemRailChargeMah != rec.modemRailChargeMah) {
oldModemRailChargeMah = rec.modemRailChargeMah;
item.append(checkin ? ",Mrc=" : " modemRailChargemAh=");
item.append(new DecimalFormat("#.##").format(oldModemRailChargeMah));
}
if (oldWifiRailChargeMah != rec.wifiRailChargeMah) {
oldWifiRailChargeMah = rec.wifiRailChargeMah;
item.append(checkin ? ",Wrc=" : " wifiRailChargemAh=");
item.append(new DecimalFormat("#.##").format(oldWifiRailChargeMah));
}
printBitDescriptions(item, oldState, rec.states, rec.wakelockTag,
HISTORY_STATE_DESCRIPTIONS, !checkin);
printBitDescriptions(item, oldState2, rec.states2, null,

View File

@@ -44,6 +44,7 @@ public final class WifiBatteryStats implements Parcelable {
private long[] mTimeInStateMs;
private long[] mTimeInSupplicantStateMs;
private long[] mTimeInRxSignalStrengthLevelMs;
private long mMonitoredRailChargeConsumedMaMs;
public static final Parcelable.Creator<WifiBatteryStats> CREATOR = new
Parcelable.Creator<WifiBatteryStats>() {
@@ -77,6 +78,7 @@ public final class WifiBatteryStats implements Parcelable {
out.writeLongArray(mTimeInStateMs);
out.writeLongArray(mTimeInRxSignalStrengthLevelMs);
out.writeLongArray(mTimeInSupplicantStateMs);
out.writeLong(mMonitoredRailChargeConsumedMaMs);
}
public void readFromParcel(Parcel in) {
@@ -96,6 +98,7 @@ public final class WifiBatteryStats implements Parcelable {
in.readLongArray(mTimeInStateMs);
in.readLongArray(mTimeInRxSignalStrengthLevelMs);
in.readLongArray(mTimeInSupplicantStateMs);
mMonitoredRailChargeConsumedMaMs = in.readLong();
}
public long getLoggingDurationMs() {
@@ -162,6 +165,10 @@ public final class WifiBatteryStats implements Parcelable {
return mTimeInSupplicantStateMs;
}
public long getMonitoredRailChargeConsumedMaMs() {
return mMonitoredRailChargeConsumedMaMs;
}
public void setLoggingDurationMs(long t) {
mLoggingDurationMs = t;
return;
@@ -245,6 +252,11 @@ public final class WifiBatteryStats implements Parcelable {
return;
}
public void setMonitoredRailChargeConsumedMaMs(long monitoredRailEnergyConsumedMaMs) {
mMonitoredRailChargeConsumedMaMs = monitoredRailEnergyConsumedMaMs;
return;
}
public int describeContents() {
return 0;
}
@@ -274,6 +286,7 @@ public final class WifiBatteryStats implements Parcelable {
Arrays.fill(mTimeInRxSignalStrengthLevelMs, 0);
mTimeInSupplicantStateMs = new long[BatteryStats.NUM_WIFI_SUPPL_STATES];
Arrays.fill(mTimeInSupplicantStateMs, 0);
mMonitoredRailChargeConsumedMaMs = 0;
return;
}
}

View File

@@ -187,6 +187,8 @@ public class BatteryStatsImpl extends BatteryStats {
static final int MSG_REPORT_RESET_STATS = 4;
static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
private static final double MILLISECONDS_IN_HOUR = 3600 * 1000;
private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
@@ -252,6 +254,9 @@ public class BatteryStatsImpl extends BatteryStats {
private static final long RPM_STATS_UPDATE_FREQ_MS = 1000;
/** Last time that RPM stats were updated by updateRpmStatsLocked. */
private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS;
/** Container for Rail Energy Data stats. */
private final RailStats mTmpRailStats = new RailStats();
/**
* Use a queue to delay removing UIDs from {@link KernelCpuUidUserSysTimeReader},
* {@link KernelCpuUidActiveTimeReader}, {@link KernelCpuUidClusterTimeReader},
@@ -327,6 +332,15 @@ public class BatteryStatsImpl extends BatteryStats {
public String getSubsystemLowPowerStats();
}
/** interface to update rail information for power monitor */
public interface RailEnergyDataCallback {
/** Function to fill the map for the rail data stats
* Used for power monitoring feature
* @param railStats
*/
void fillRailDataStats(RailStats railStats);
}
public static abstract class UserInfoProvider {
private int[] userIds;
protected abstract @Nullable int[] getUserIds();
@@ -361,6 +375,8 @@ public class BatteryStatsImpl extends BatteryStats {
}
};
public final RailEnergyDataCallback mRailEnergyDataCallback;
/**
* This handler is running on {@link BackgroundThread}.
*/
@@ -593,7 +609,9 @@ public class BatteryStatsImpl extends BatteryStats {
int UPDATE_RADIO = 0x04;
int UPDATE_BT = 0x08;
int UPDATE_RPM = 0x10; // 16
int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM;
int UPDATE_RAIL = 0x20; // 32
int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM
| UPDATE_RAIL;
Future<?> scheduleSync(String reason, int flags);
Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
@@ -1078,6 +1096,7 @@ public class BatteryStatsImpl extends BatteryStats {
mBatteryStatsHistory = null;
mHandler = null;
mPlatformIdleStateCallback = null;
mRailEnergyDataCallback = null;
mUserInfoProvider = null;
mConstants = new Constants(mHandler);
clearHistoryLocked();
@@ -3005,6 +3024,7 @@ public class BatteryStatsImpl extends BatteryStats {
private final LongSamplingCounter mRxTimeMillis;
private final LongSamplingCounter[] mTxTimeMillis;
private final LongSamplingCounter mPowerDrainMaMs;
private final LongSamplingCounter mMonitoredRailChargeConsumedMaMs;
public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) {
mIdleTimeMillis = new LongSamplingCounter(timeBase);
@@ -3016,6 +3036,7 @@ public class BatteryStatsImpl extends BatteryStats {
mTxTimeMillis[i] = new LongSamplingCounter(timeBase);
}
mPowerDrainMaMs = new LongSamplingCounter(timeBase);
mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase);
}
public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) {
@@ -3033,6 +3054,7 @@ public class BatteryStatsImpl extends BatteryStats {
mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in);
}
mPowerDrainMaMs = new LongSamplingCounter(timeBase, in);
mMonitoredRailChargeConsumedMaMs = new LongSamplingCounter(timeBase, in);
}
public void readSummaryFromParcel(Parcel in) {
@@ -3048,6 +3070,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.readSummaryFromParcelLocked(in);
}
mPowerDrainMaMs.readSummaryFromParcelLocked(in);
mMonitoredRailChargeConsumedMaMs.readSummaryFromParcelLocked(in);
}
@Override
@@ -3065,6 +3088,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.writeSummaryFromParcelLocked(dest);
}
mPowerDrainMaMs.writeSummaryFromParcelLocked(dest);
mMonitoredRailChargeConsumedMaMs.writeSummaryFromParcelLocked(dest);
}
@Override
@@ -3078,6 +3102,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.writeToParcel(dest);
}
mPowerDrainMaMs.writeToParcel(dest);
mMonitoredRailChargeConsumedMaMs.writeToParcel(dest);
}
public void reset(boolean detachIfReset) {
@@ -3089,6 +3114,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.reset(detachIfReset);
}
mPowerDrainMaMs.reset(detachIfReset);
mMonitoredRailChargeConsumedMaMs.reset(detachIfReset);
}
public void detach() {
@@ -3100,6 +3126,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.detach();
}
mPowerDrainMaMs.detach();
mMonitoredRailChargeConsumedMaMs.detach();
}
/**
@@ -3154,6 +3181,15 @@ public class BatteryStatsImpl extends BatteryStats {
public LongSamplingCounter getPowerCounter() {
return mPowerDrainMaMs;
}
/**
* @return a LongSamplingCounter, measuring actual monitored rail energy consumed
* milli-ampere milli-seconds (mAmS).
*/
@Override
public LongSamplingCounter getMonitoredRailChargeConsumedMaMs() {
return mMonitoredRailChargeConsumedMaMs;
}
}
/** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */
@@ -3497,6 +3533,8 @@ public class BatteryStatsImpl extends BatteryStats {
if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh);
dest.writeInt(cur.batteryChargeUAh);
}
dest.writeDouble(cur.modemRailChargeMah);
dest.writeDouble(cur.wifiRailChargeMah);
}
private int buildBatteryLevelInt(HistoryItem h) {
@@ -3747,6 +3785,8 @@ public class BatteryStatsImpl extends BatteryStats {
if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) {
cur.batteryChargeUAh = src.readInt();
}
cur.modemRailChargeMah = src.readDouble();
cur.wifiRailChargeMah = src.readDouble();
}
@Override
@@ -10111,12 +10151,12 @@ public class BatteryStatsImpl extends BatteryStats {
}
public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb,
UserInfoProvider userInfoProvider) {
this(new SystemClocks(), systemDir, handler, cb, userInfoProvider);
RailEnergyDataCallback railStatsCb, UserInfoProvider userInfoProvider) {
this(new SystemClocks(), systemDir, handler, cb, railStatsCb, userInfoProvider);
}
private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler,
PlatformIdleStateCallback cb,
PlatformIdleStateCallback cb, RailEnergyDataCallback railStatsCb,
UserInfoProvider userInfoProvider) {
init(clocks);
@@ -10218,6 +10258,7 @@ public class BatteryStatsImpl extends BatteryStats {
clearHistoryLocked();
updateDailyDeadlineLocked();
mPlatformIdleStateCallback = cb;
mRailEnergyDataCallback = railStatsCb;
mUserInfoProvider = userInfoProvider;
}
@@ -10238,6 +10279,7 @@ public class BatteryStatsImpl extends BatteryStats {
mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer);
readFromParcel(p);
mPlatformIdleStateCallback = null;
mRailEnergyDataCallback = null;
}
public void setPowerProfileLocked(PowerProfile profile) {
@@ -10934,6 +10976,8 @@ public class BatteryStatsImpl extends BatteryStats {
mWakeupReasonStats.clear();
}
mTmpRailStats.reset();
mLastHistoryStepDetails = null;
mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
@@ -11321,6 +11365,16 @@ public class BatteryStatsImpl extends BatteryStats {
mWifiActivity.getPowerCounter().addCountLocked(
(long) (info.getControllerEnergyUsed() / opVolt));
}
// Converting uWs to mAms.
// Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms
long monitoredRailChargeConsumedMaMs =
(long) (mTmpRailStats.getWifiTotalEnergyUseduWs() / opVolt);
mWifiActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked(
monitoredRailChargeConsumedMaMs);
mHistoryCur.wifiRailChargeMah +=
(monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
mTmpRailStats.resetWifiTotalEnergyUsed();
}
}
}
@@ -11411,9 +11465,18 @@ public class BatteryStatsImpl extends BatteryStats {
// We store the power drain as mAms.
mModemActivity.getPowerCounter().addCountLocked((long) energyUsed);
// Converting uWs to mAms.
// Conversion: (uWs * (1000ms / 1s) * (1mW / 1000uW)) / mV = mAms
long monitoredRailChargeConsumedMaMs =
(long) (mTmpRailStats.getCellularTotalEnergyUseduWs() / opVolt);
mModemActivity.getMonitoredRailChargeConsumedMaMs().addCountLocked(
monitoredRailChargeConsumedMaMs);
mHistoryCur.modemRailChargeMah +=
(monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR);
addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
mTmpRailStats.resetCellularTotalEnergyUsed();
}
}
final long elapsedRealtimeMs = mClocks.elapsedRealtime();
long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
elapsedRealtimeMs * 1000);
@@ -11811,6 +11874,16 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
/**
* Read and record Rail Energy data.
*/
public void updateRailStatsLocked() {
if (mRailEnergyDataCallback == null || !mTmpRailStats.isRailStatsAvailable()) {
return;
}
mRailEnergyDataCallback.fillRailDataStats(mTmpRailStats);
}
/**
* Read and distribute kernel wake lock use across apps.
*/
@@ -12950,6 +13023,8 @@ public class BatteryStatsImpl extends BatteryStats {
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
final long monitoredRailChargeConsumedMaMs =
counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which);
long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES];
for (int i = 0; i < timeInRatMs.length; i++) {
timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000;
@@ -12979,58 +13054,62 @@ public class BatteryStatsImpl extends BatteryStats {
s.setTimeInRatMs(timeInRatMs);
s.setTimeInRxSignalStrengthLevelMs(timeInRxSignalStrengthLevelMs);
s.setTxTimeMs(txTimeMs);
s.setMonitoredRailChargeConsumedMaMs(monitoredRailChargeConsumedMaMs);
return s;
}
/*@hide */
public WifiBatteryStats getWifiBatteryStats() {
WifiBatteryStats s = new WifiBatteryStats();
final int which = STATS_SINCE_CHARGED;
final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
final ControllerActivityCounter counter = getWifiControllerActivity();
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
final long totalControllerActivityTimeMs
= computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
final long sleepTimeMs
= totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs);
final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
long numAppScanRequest = 0;
for (int i = 0; i < mUidStats.size(); i++) {
numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which);
}
long[] timeInStateMs = new long[NUM_WIFI_STATES];
for (int i=0; i<NUM_WIFI_STATES; i++) {
/*@hide */
public WifiBatteryStats getWifiBatteryStats() {
WifiBatteryStats s = new WifiBatteryStats();
final int which = STATS_SINCE_CHARGED;
final long rawRealTime = SystemClock.elapsedRealtime() * 1000;
final ControllerActivityCounter counter = getWifiControllerActivity();
final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
final long totalControllerActivityTimeMs
= computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
final long sleepTimeMs
= totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs);
final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
final long monitoredRailChargeConsumedMaMs =
counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which);
long numAppScanRequest = 0;
for (int i = 0; i < mUidStats.size(); i++) {
numAppScanRequest += mUidStats.valueAt(i).mWifiScanTimer.getCountLocked(which);
}
long[] timeInStateMs = new long[NUM_WIFI_STATES];
for (int i=0; i<NUM_WIFI_STATES; i++) {
timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000;
}
long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES];
for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000;
}
long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS];
for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000;
}
s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000);
s.setKernelActiveTimeMs(getWifiActiveTime(rawRealTime, which) / 1000);
s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
s.setNumBytesTx(getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
s.setNumBytesRx(getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
s.setSleepTimeMs(sleepTimeMs);
s.setIdleTimeMs(idleTimeMs);
s.setRxTimeMs(rxTimeMs);
s.setTxTimeMs(txTimeMs);
s.setScanTimeMs(scanTimeMs);
s.setEnergyConsumedMaMs(energyConsumedMaMs);
s.setNumAppScanRequest(numAppScanRequest);
s.setTimeInStateMs(timeInStateMs);
s.setTimeInSupplicantStateMs(timeInSupplStateMs);
s.setTimeInRxSignalStrengthLevelMs(timeSignalStrengthTimeMs);
return s;
}
}
long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES];
for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000;
}
long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS];
for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000;
}
s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000);
s.setKernelActiveTimeMs(getWifiActiveTime(rawRealTime, which) / 1000);
s.setNumPacketsTx(getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which));
s.setNumBytesTx(getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which));
s.setNumPacketsRx(getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which));
s.setNumBytesRx(getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which));
s.setSleepTimeMs(sleepTimeMs);
s.setIdleTimeMs(idleTimeMs);
s.setRxTimeMs(rxTimeMs);
s.setTxTimeMs(txTimeMs);
s.setScanTimeMs(scanTimeMs);
s.setEnergyConsumedMaMs(energyConsumedMaMs);
s.setNumAppScanRequest(numAppScanRequest);
s.setTimeInStateMs(timeInStateMs);
s.setTimeInSupplicantStateMs(timeInSupplStateMs);
s.setTimeInRxSignalStrengthLevelMs(timeSignalStrengthTimeMs);
s.setMonitoredRailChargeConsumedMaMs(monitoredRailChargeConsumedMaMs);
return s;
}
/*@hide */
public GpsBatteryStats getGpsBatteryStats() {

View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.os;
import android.util.ArrayMap;
import android.util.Slog;
import java.util.Map;
/** Rail Stats Power Monitoring Class */
public final class RailStats {
private static final String TAG = "RailStats";
private static final String WIFI_SUBSYSTEM = "wifi";
private static final String CELLULAR_SUBSYSTEM = "cellular";
private Map<Long, RailInfoData> mRailInfoData = new ArrayMap<>();
private long mCellularTotalEnergyUseduWs = 0;
private long mWifiTotalEnergyUseduWs = 0;
private boolean mRailStatsAvailability = true;
/** Updates the rail data map of all power monitor rails being monitored
* Function is called from native side
* @param index
* @param railName
* @param subSystemName
* @param timestampSinceBootMs
* @param energyUsedSinceBootuWs
*/
public void updateRailData(long index, String railName, String subSystemName,
long timestampSinceBootMs, long energyUsedSinceBootuWs) {
if (!(subSystemName.equals(WIFI_SUBSYSTEM) || subSystemName.equals(CELLULAR_SUBSYSTEM))) {
return;
}
RailInfoData node = mRailInfoData.get(index);
if (node == null) {
mRailInfoData.put(index, new RailInfoData(index, railName, subSystemName,
timestampSinceBootMs, energyUsedSinceBootuWs));
if (subSystemName.equals(WIFI_SUBSYSTEM)) {
mWifiTotalEnergyUseduWs += energyUsedSinceBootuWs;
return;
}
if (subSystemName.equals(CELLULAR_SUBSYSTEM)) {
mCellularTotalEnergyUseduWs += energyUsedSinceBootuWs;
}
return;
}
long timeSinceLastLogMs = timestampSinceBootMs - node.timestampSinceBootMs;
long energyUsedSinceLastLoguWs = energyUsedSinceBootuWs - node.energyUsedSinceBootuWs;
if (timeSinceLastLogMs < 0 || energyUsedSinceLastLoguWs < 0) {
energyUsedSinceLastLoguWs = node.energyUsedSinceBootuWs;
}
node.timestampSinceBootMs = timestampSinceBootMs;
node.energyUsedSinceBootuWs = energyUsedSinceBootuWs;
if (subSystemName.equals(WIFI_SUBSYSTEM)) {
mWifiTotalEnergyUseduWs += energyUsedSinceLastLoguWs;
return;
}
if (subSystemName.equals(CELLULAR_SUBSYSTEM)) {
mCellularTotalEnergyUseduWs += energyUsedSinceLastLoguWs;
}
}
/** resets the cellular total energy used aspect.
*/
public void resetCellularTotalEnergyUsed() {
mCellularTotalEnergyUseduWs = 0;
}
/** resets the wifi total energy used aspect.
*/
public void resetWifiTotalEnergyUsed() {
mWifiTotalEnergyUseduWs = 0;
}
public long getCellularTotalEnergyUseduWs() {
return mCellularTotalEnergyUseduWs;
}
public long getWifiTotalEnergyUseduWs() {
return mWifiTotalEnergyUseduWs;
}
/** reset the total energy subsystems
*
*/
public void reset() {
mCellularTotalEnergyUseduWs = 0;
mWifiTotalEnergyUseduWs = 0;
}
public RailStats getRailStats() {
return this;
}
public void setRailStatsAvailability(boolean railStatsAvailability) {
mRailStatsAvailability = railStatsAvailability;
}
public boolean isRailStatsAvailable() {
return mRailStatsAvailability;
}
/** Container class to contain rail data information */
public static class RailInfoData {
private static final String TAG = "RailInfoData";
public long index;
public String railName;
public String subSystemName;
public long timestampSinceBootMs;
public long energyUsedSinceBootuWs;
private RailInfoData(long index, String railName, String subSystemName,
long timestampSinceBootMs, long energyUsedSinceBoot) {
this.index = index;
this.railName = railName;
this.subSystemName = subSystemName;
this.timestampSinceBootMs = timestampSinceBootMs;
this.energyUsedSinceBootuWs = energyUsedSinceBoot;
}
/** print the rail data
*
*/
public void printData() {
Slog.d(TAG, "Index = " + index);
Slog.d(TAG, "RailName = " + railName);
Slog.d(TAG, "SubSystemName = " + subSystemName);
Slog.d(TAG, "TimestampSinceBootMs = " + timestampSinceBootMs);
Slog.d(TAG, "EnergyUsedSinceBootuWs = " + energyUsedSinceBootuWs);
}
}
}

View File

@@ -58,6 +58,10 @@ message ControllerActivityProto {
optional int64 duration_ms = 2;
}
repeated TxLevel tx = 4;
// Total rail charge consumed by the monitored rails by the controller. The value may
// always be 0 if the device doesn't support monitored rail calculations.
optional double monitored_rail_charge_mah = 5;
}
message SystemProto {

View File

@@ -477,6 +477,10 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
mStats.updateRpmStatsLocked();
}
if ((updateFlags & UPDATE_RAIL) != 0) {
mStats.updateRailStatsLocked();
}
if (bluetoothInfo != null) {
if (bluetoothInfo.isValid()) {
mStats.updateBluetoothStateLocked(bluetoothInfo);

View File

@@ -59,6 +59,7 @@ import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.PowerProfile;
import com.android.internal.os.RailStats;
import com.android.internal.os.RpmStats;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.ParseUtils;
@@ -84,7 +85,8 @@ import java.util.concurrent.Future;
*/
public final class BatteryStatsService extends IBatteryStats.Stub
implements PowerManagerInternal.LowPowerModeListener,
BatteryStatsImpl.PlatformIdleStateCallback {
BatteryStatsImpl.PlatformIdleStateCallback,
BatteryStatsImpl.RailEnergyDataCallback {
static final String TAG = "BatteryStatsService";
static final boolean DBG = false;
@@ -98,6 +100,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
private native void getLowPowerStats(RpmStats rpmStats);
private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
private native int getSubsystemLowPowerStats(ByteBuffer outBuffer);
private native void getRailEnergyPowerStats(RailStats railStats);
private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
@@ -120,6 +123,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
}
@Override
public void fillRailDataStats(RailStats railStats) {
if (DBG) Slog.d(TAG, "begin getRailEnergyPowerStats");
try {
getRailEnergyPowerStats(railStats);
} finally {
if (DBG) Slog.d(TAG, "end getRailEnergyPowerStats");
}
}
@Override
public String getPlatformLowPowerStats() {
if (DBG) Slog.d(TAG, "begin getPlatformLowPowerStats");
@@ -177,7 +190,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return (umi != null) ? umi.getUserIds() : null;
}
};
mStats = new BatteryStatsImpl(systemDir, handler, this, mUserManagerUserInfoProvider);
mStats = new BatteryStatsImpl(systemDir, handler, this,
this, mUserManagerUserInfoProvider);
mWorker = new BatteryExternalStatsWorker(context, mStats);
mStats.setExternalStatsSyncLocked(mWorker);
mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
@@ -1460,7 +1474,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
in.unmarshall(raw, 0, raw.length);
in.setDataPosition(0);
BatteryStatsImpl checkinStats = new BatteryStatsImpl(
null, mStats.mHandler, null, mUserManagerUserInfoProvider);
null, mStats.mHandler, null, null,
mUserManagerUserInfoProvider);
checkinStats.readSummaryFromParcel(in);
in.recycle();
checkinStats.dumpProtoLocked(
@@ -1498,7 +1513,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
in.unmarshall(raw, 0, raw.length);
in.setDataPosition(0);
BatteryStatsImpl checkinStats = new BatteryStatsImpl(
null, mStats.mHandler, null, mUserManagerUserInfoProvider);
null, mStats.mHandler, null, null,
mUserManagerUserInfoProvider);
checkinStats.readSummaryFromParcel(in);
in.recycle();
checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,

View File

@@ -17,6 +17,7 @@
#define LOG_TAG "BatteryStatsService"
//#define LOG_NDEBUG 0
#include <climits>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -28,6 +29,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <unordered_map>
#include <utility>
#include <android/hardware/power/1.0/IPower.h>
#include <android/hardware/power/1.1/IPower.h>
@@ -87,6 +89,15 @@ std::function<void(JNIEnv*, jobject)> gGetLowPowerStatsImpl = {};
std::function<jint(JNIEnv*, jobject)> gGetPlatformLowPowerStatsImpl = {};
std::function<jint(JNIEnv*, jobject)> gGetSubsystemLowPowerStatsImpl = {};
// Cellular/Wifi power monitor rail information
static jmethodID jupdateRailData = NULL;
static jmethodID jsetRailStatsAvailability = NULL;
std::function<void(JNIEnv*, jobject)> gGetRailEnergyPowerStatsImpl = {};
std::unordered_map<uint32_t, std::pair<std::string, std::string>> gPowerStatsHalRailNames = {};
static bool power_monitor_available = false;
// The caller must be holding gPowerHalMutex.
static void deinitPowerStatsLocked() {
gPowerStatsHalV1_0 = nullptr;
@@ -258,6 +269,7 @@ static bool initializePowerStats() {
gPowerStatsHalStateNames.clear();
gPowerStatsHalPlatformIds.clear();
gPowerStatsHalSubsystemIds.clear();
gPowerStatsHalRailNames.clear();
Return<void> ret;
ret = gPowerStatsHalV1_0->getPowerEntityInfo([](auto infos, auto status) {
@@ -301,6 +313,27 @@ static bool initializePowerStats() {
return false;
}
// Get Power monitor rails available
ret = gPowerStatsHalV1_0->getRailInfo([](auto rails, auto status) {
if (status != Status::SUCCESS) {
ALOGW("Rail information is not available");
power_monitor_available = false;
return;
}
// Fill out rail names/subsystems into gPowerStatsHalRailNames
for (auto rail : rails) {
gPowerStatsHalRailNames.emplace(rail.index,
std::make_pair(rail.railName, rail.subsysName));
}
if (!gPowerStatsHalRailNames.empty()) {
power_monitor_available = true;
}
});
if (!checkResultLocked(ret, __func__)) {
return false;
}
return (!gPowerStatsHalEntityNames.empty()) && (!gPowerStatsHalStateNames.empty());
}
@@ -517,6 +550,50 @@ static jint getPowerStatsHalSubsystemData(JNIEnv* env, jobject outBuf) {
return total_added;
}
static void getPowerStatsHalRailEnergyData(JNIEnv* env, jobject jrailStats) {
using android::hardware::power::stats::V1_0::Status;
using android::hardware::power::stats::V1_0::EnergyData;
if (!getPowerStatsHalLocked()) {
ALOGE("failed to get power stats");
return;
}
if (!power_monitor_available) {
env->CallVoidMethod(jrailStats, jsetRailStatsAvailability, false);
ALOGW("Rail energy data is not available");
return;
}
// Get power rail energySinceBoot data
Return<void> ret = gPowerStatsHalV1_0->getEnergyData({},
[&env, &jrailStats](auto energyData, auto status) {
if (status == Status::NOT_SUPPORTED) {
ALOGW("getEnergyData is not supported");
return;
}
for (auto data : energyData) {
if (!(data.timestamp > LLONG_MAX || data.energy > LLONG_MAX)) {
env->CallVoidMethod(jrailStats,
jupdateRailData,
data.index,
env->NewStringUTF(
gPowerStatsHalRailNames.at(data.index).first.c_str()),
env->NewStringUTF(
gPowerStatsHalRailNames.at(data.index).second.c_str()),
data.timestamp,
data.energy);
} else {
ALOGE("Java long overflow seen. Rail index %d not updated", data.index);
}
}
});
if (!checkResultLocked(ret, __func__)) {
ALOGE("getEnergyData failed");
}
}
// The caller must be holding powerHalMutex.
static void getPowerHalLowPowerData(JNIEnv* env, jobject jrpmStats) {
sp<IPowerV1_0> powerHalV1_0 = getPowerHalV1_0();
@@ -761,11 +838,13 @@ static void setUpPowerStatsLocked() {
gGetLowPowerStatsImpl = getPowerStatsHalLowPowerData;
gGetPlatformLowPowerStatsImpl = getPowerStatsHalPlatformData;
gGetSubsystemLowPowerStatsImpl = getPowerStatsHalSubsystemData;
gGetRailEnergyPowerStatsImpl = getPowerStatsHalRailEnergyData;
} else if (android::hardware::power::V1_0::IPower::getService() != nullptr) {
ALOGI("Using power HAL");
gGetLowPowerStatsImpl = getPowerHalLowPowerData;
gGetPlatformLowPowerStatsImpl = getPowerHalPlatformData;
gGetSubsystemLowPowerStatsImpl = getPowerHalSubsystemData;
gGetRailEnergyPowerStatsImpl = NULL;
}
}
@@ -835,11 +914,44 @@ static jint getSubsystemLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject
return -1;
}
static void getRailEnergyPowerStats(JNIEnv* env, jobject /* clazz */, jobject jrailStats) {
if (jrailStats == NULL) {
jniThrowException(env, "java/lang/NullPointerException",
"The railstats jni input jobject jrailStats is null.");
return;
}
if (jupdateRailData == NULL) {
ALOGE("A railstats jni jmethodID is null.");
return;
}
std::lock_guard<std::mutex> lock(gPowerHalMutex);
if (!gGetRailEnergyPowerStatsImpl) {
setUpPowerStatsLocked();
}
if (gGetRailEnergyPowerStatsImpl) {
gGetRailEnergyPowerStatsImpl(env, jrailStats);
return;
}
if (jsetRailStatsAvailability == NULL) {
ALOGE("setRailStatsAvailability jni jmethodID is null.");
return;
}
env->CallVoidMethod(jrailStats, jsetRailStatsAvailability, false);
ALOGE("Unable to load Power.Stats.HAL. Setting rail availability to false");
return;
}
static const JNINativeMethod method_table[] = {
{ "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup },
{ "getLowPowerStats", "(Lcom/android/internal/os/RpmStats;)V", (void*)getLowPowerStats },
{ "getPlatformLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getPlatformLowPowerStats },
{ "getSubsystemLowPowerStats", "(Ljava/nio/ByteBuffer;)I", (void*)getSubsystemLowPowerStats },
{ "getRailEnergyPowerStats", "(Lcom/android/internal/os/RailStats;)V",
(void*)getRailEnergyPowerStats },
};
int register_android_server_BatteryStatsService(JNIEnv *env)
@@ -850,8 +962,9 @@ int register_android_server_BatteryStatsService(JNIEnv *env)
env->FindClass("com/android/internal/os/RpmStats$PowerStatePlatformSleepState");
jclass clsPowerStateSubsystem =
env->FindClass("com/android/internal/os/RpmStats$PowerStateSubsystem");
jclass clsRailStats = env->FindClass("com/android/internal/os/RailStats");
if (clsRpmStats == NULL || clsPowerStatePlatformSleepState == NULL
|| clsPowerStateSubsystem == NULL) {
|| clsPowerStateSubsystem == NULL || clsRailStats == NULL) {
ALOGE("A rpmstats jni jclass is null.");
} else {
jgetAndUpdatePlatformState = env->GetMethodID(clsRpmStats, "getAndUpdatePlatformState",
@@ -862,6 +975,10 @@ int register_android_server_BatteryStatsService(JNIEnv *env)
"(Ljava/lang/String;JI)V");
jputState = env->GetMethodID(clsPowerStateSubsystem, "putState",
"(Ljava/lang/String;JI)V");
jupdateRailData = env->GetMethodID(clsRailStats, "updateRailData",
"(JLjava/lang/String;Ljava/lang/String;JJ)V");
jsetRailStatsAvailability = env->GetMethodID(clsRailStats, "setRailStatsAvailability",
"(Z)V");
}
return jniRegisterNativeMethods(env, "com/android/server/am/BatteryStatsService",