summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java113
1 files changed, 89 insertions, 24 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 33b55ac2f0a0..7f8788529714 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -11492,10 +11492,10 @@ public class BatteryStatsImpl extends BatteryStats {
return;
}
- final ArrayMap<Uid, Double> uidEstimatedConsumptionMah =
+ final SparseDoubleArray uidEstimatedConsumptionMah =
(mGlobalMeasuredEnergyStats != null
&& mWifiPowerCalculator != null && consumedChargeUC > 0) ?
- new ArrayMap<>() : null;
+ new SparseDoubleArray() : null;
double totalEstimatedConsumptionMah = 0;
SparseLongArray rxPackets = new SparseLongArray();
@@ -11583,7 +11583,7 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- addDoubleToUidMap(uidEstimatedConsumptionMah, u,
+ uidEstimatedConsumptionMah.add(u.getUid(),
mWifiPowerCalculator.calcPowerWithoutControllerDataMah(
entry.rxPackets, entry.txPackets,
uidRunningMs, uidScanMs, uidBatchScanMs));
@@ -11709,7 +11709,7 @@ public class BatteryStatsImpl extends BatteryStats {
if (uidEstimatedConsumptionMah != null) {
double uidEstMah = mWifiPowerCalculator.calcPowerFromControllerDataMah(
scanRxTimeSinceMarkMs, scanTxTimeSinceMarkMs, myIdleTimeMs);
- addDoubleToUidMap(uidEstimatedConsumptionMah, uid, uidEstMah);
+ uidEstimatedConsumptionMah.add(uid.getUid(), uidEstMah);
}
}
@@ -11731,7 +11731,7 @@ public class BatteryStatsImpl extends BatteryStats {
uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0]
.addCountLocked(myTxTimeMs);
if (uidEstimatedConsumptionMah != null) {
- addDoubleToUidMap(uidEstimatedConsumptionMah, uid,
+ uidEstimatedConsumptionMah.add(uid.getUid(),
mWifiPowerCalculator.calcPowerFromControllerDataMah(
0, myTxTimeMs, 0));
}
@@ -11750,7 +11750,7 @@ public class BatteryStatsImpl extends BatteryStats {
uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter()
.addCountLocked(myRxTimeMs);
if (uidEstimatedConsumptionMah != null) {
- addDoubleToUidMap(uidEstimatedConsumptionMah, uid,
+ uidEstimatedConsumptionMah.add(uid.getUid(),
mWifiPowerCalculator.calcPowerFromControllerDataMah(
myRxTimeMs, 0, 0));
}
@@ -12086,10 +12086,10 @@ public class BatteryStatsImpl extends BatteryStats {
Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
}
- final ArrayMap<Uid, Double> uidEstimatedConsumptionMah =
+ final SparseDoubleArray uidEstimatedConsumptionMah =
(mGlobalMeasuredEnergyStats != null
&& mBluetoothPowerCalculator != null && consumedChargeUC > 0) ?
- new ArrayMap<>() : null;
+ new SparseDoubleArray() : null;
long totalScanTimeMs = 0;
@@ -12150,7 +12150,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs);
if (uidEstimatedConsumptionMah != null) {
- addDoubleToUidMap(uidEstimatedConsumptionMah, u,
+ uidEstimatedConsumptionMah.add(u.getUid(),
mBluetoothPowerCalculator.calculatePowerMah(
scanTimeRxSinceMarkMs, scanTimeTxSinceMarkMs, 0));
}
@@ -12217,7 +12217,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.getRxTimeCounter().addCountLocked(timeRxMs);
if (uidEstimatedConsumptionMah != null) {
- addDoubleToUidMap(uidEstimatedConsumptionMah, u,
+ uidEstimatedConsumptionMah.add(u.getUid(),
mBluetoothPowerCalculator.calculatePowerMah(timeRxMs, 0, 0));
}
}
@@ -12230,7 +12230,7 @@ public class BatteryStatsImpl extends BatteryStats {
counter.getTxTimeCounters()[0].addCountLocked(timeTxMs);
if (uidEstimatedConsumptionMah != null) {
- addDoubleToUidMap(uidEstimatedConsumptionMah, u,
+ uidEstimatedConsumptionMah.add(u.getUid(),
mBluetoothPowerCalculator.calculatePowerMah(0, timeTxMs, 0));
}
}
@@ -12452,7 +12452,7 @@ public class BatteryStatsImpl extends BatteryStats {
// If multidisplay becomes a reality, this is probably more reasonable than pooling.
// On the first pass, collect total time since mark so that we can normalize power.
- final ArrayMap<Uid, Double> fgTimeUsArray = new ArrayMap<>();
+ final SparseDoubleArray fgTimeUsArray = new SparseDoubleArray();
final long elapsedRealtimeUs = elapsedRealtimeMs * 1000;
// TODO(b/175726779): Update and optimize the algorithm (e.g. avoid iterating over ALL uids)
final int uidStatsSize = mUidStats.size();
@@ -12460,7 +12460,7 @@ public class BatteryStatsImpl extends BatteryStats {
final Uid uid = mUidStats.valueAt(i);
final long fgTimeUs = uid.markProcessForegroundTimeUs(elapsedRealtimeMs, true);
if (fgTimeUs == 0) continue;
- fgTimeUsArray.put(uid, (double) fgTimeUs);
+ fgTimeUsArray.put(uid.getUid(), (double) fgTimeUs);
}
distributeEnergyToUidsLocked(powerBucket, chargeUC, fgTimeUsArray, 0);
}
@@ -12523,10 +12523,11 @@ public class BatteryStatsImpl extends BatteryStats {
* <p>A consequence of minRatioDenominator is that the sum over all uids might be less than
* totalConsumedChargeUC. This is intentional; the remainder is purposefully unnaccounted rather
* than incorrectly blamed on uids, and implies unknown (non-uid) sources of drain.
+ *
+ * <p>All uids in ratioNumerators must exist in mUidStats already.
*/
- // TODO(b/182845832): Use some sort of "SparseDoubleArray" instead of ArrayMap<Uid, Double>.
private void distributeEnergyToUidsLocked(@StandardPowerBucket int bucket,
- long totalConsumedChargeUC, ArrayMap<Uid, Double> ratioNumerators,
+ long totalConsumedChargeUC, SparseDoubleArray ratioNumerators,
double minRatioDenominator) {
// If the sum of all app usage was greater than the total, use that instead:
@@ -12538,7 +12539,7 @@ public class BatteryStatsImpl extends BatteryStats {
if (ratioDenominator <= 0) return;
for (int i = ratioNumerators.size() - 1; i >= 0; i--) {
- final Uid uid = ratioNumerators.keyAt(i);
+ final Uid uid = getAvailableUidStatsLocked(ratioNumerators.keyAt(i));
final double ratioNumerator = ratioNumerators.valueAt(i);
final long uidActualUC
= (long) (totalConsumedChargeUC * ratioNumerator / ratioDenominator + 0.5);
@@ -12546,15 +12547,79 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- /** Adds the summand to the value stored in uidMap for the given uid. */
- // TODO(b/182845832): Use some sort of "SparseDoubleArray" instead of ArrayMap<Uid, Double>.
- private static void addDoubleToUidMap(ArrayMap<Uid, Double> uidMap, Uid uid, double summand) {
- if (uidMap == null) return;
- final Double oldVal = uidMap.get(uid);
- if (oldVal != null) {
- summand += oldVal;
+ /**
+ * SparseDoubleArray map integers to doubles.
+ * Its implementation is the same as that of {@link SparseLongArray}; see there for details.
+ *
+ * @see SparseLongArray
+ */
+ private static class SparseDoubleArray {
+ /**
+ * The int->double map, but storing the doubles as longs using
+ * {@link Double.doubleToRawLongBits(double)}.
+ */
+ private final SparseLongArray mValues = new SparseLongArray();
+
+ /**
+ * Gets the double mapped from the specified key, or <code>0</code>
+ * if no such mapping has been made.
+ */
+ public double get(int key) {
+ if (mValues.indexOfKey(key) >= 0) {
+ return Double.longBitsToDouble(mValues.get(key));
+ }
+ return 0;
+ }
+
+ /**
+ * Adds a mapping from the specified key to the specified value,
+ * replacing the previous mapping from the specified key if there
+ * was one.
+ */
+ public void put(int key, double value) {
+ mValues.put(key, Double.doubleToRawLongBits(value));
+ }
+
+ /**
+ * Adds a mapping from the specified key to the specified value,
+ * <b>adding</b> to the previous mapping from the specified key if there
+ * was one.
+ */
+ public void add(int key, double summand) {
+ final double oldValue = get(key);
+ put(key, oldValue + summand);
}
- uidMap.put(uid, summand);
+
+ /**
+ * Returns the number of key-value mappings that this SparseDoubleArray
+ * currently stores.
+ */
+ public int size() {
+ return mValues.size();
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns
+ * the key from the <code>index</code>th key-value mapping that this
+ * SparseDoubleArray stores.
+ *
+ * @see SparseLongArray#keyAt(int)
+ */
+ public int keyAt(int index) {
+ return mValues.keyAt(index);
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns
+ * the value from the <code>index</code>th key-value mapping that this
+ * SparseDoubleArray stores.
+ *
+ * @see SparseLongArray#valueAt(int)
+ */
+ public double valueAt(int index) {
+ return Double.longBitsToDouble(mValues.valueAt(index));
+ }
+
}
/**