Loading core/java/android/os/BatteryUsageStatsQuery.java +24 −0 Original line number Diff line number Diff line Loading @@ -60,14 +60,18 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 2; private static final long DEFAULT_MAX_STATS_AGE_MS = 5 * 60 * 1000; private final int mFlags; @NonNull private final int[] mUserIds; private final long mMaxStatsAgeMs; private BatteryUsageStatsQuery(@NonNull Builder builder) { mFlags = builder.mFlags; mUserIds = builder.mUserIds != null ? builder.mUserIds.toArray() : new int[]{UserHandle.USER_ALL}; mMaxStatsAgeMs = builder.mMaxStatsAgeMs; } @BatteryUsageStatsFlags Loading @@ -94,10 +98,19 @@ public final class BatteryUsageStatsQuery implements Parcelable { return (mFlags & FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL) != 0; } /** * Returns the client's tolerance for stale battery stats. The data is allowed to be up to * this many milliseconds out-of-date. */ public long getMaxStatsAge() { return mMaxStatsAgeMs; } private BatteryUsageStatsQuery(Parcel in) { mFlags = in.readInt(); mUserIds = new int[in.readInt()]; in.readIntArray(mUserIds); mMaxStatsAgeMs = in.readLong(); } @Override Loading @@ -105,6 +118,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { dest.writeInt(mFlags); dest.writeInt(mUserIds.length); dest.writeIntArray(mUserIds); dest.writeLong(mMaxStatsAgeMs); } @Override Loading Loading @@ -132,6 +146,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { public static final class Builder { private int mFlags; private IntArray mUserIds; private long mMaxStatsAgeMs = DEFAULT_MAX_STATS_AGE_MS; /** * Builds a read-only BatteryUsageStatsQuery object. Loading Loading @@ -170,5 +185,14 @@ public final class BatteryUsageStatsQuery implements Parcelable { mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL; return this; } /** * Set the client's tolerance for stale battery stats. The data may be up to * this many milliseconds out-of-date. */ public Builder setMaxStatsAgeMs(long maxStatsAgeMs) { mMaxStatsAgeMs = maxStatsAgeMs; return this; } } } core/java/com/android/internal/os/BatteryStatsImpl.java +2 −0 Original line number Diff line number Diff line Loading @@ -16525,6 +16525,8 @@ public class BatteryStatsImpl extends BatteryStats { // Pull the clock time. This may update the time and make a new history entry // if we had originally pulled a time before the RTC was set. getStartClockTime(); updateSystemServiceCallStats(); } public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) { core/java/com/android/internal/os/BatteryUsageStatsProvider.java +20 −20 Original line number Diff line number Diff line Loading @@ -21,9 +21,7 @@ import android.hardware.SensorManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Bundle; import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -88,30 +86,32 @@ public class BatteryUsageStatsProvider { } /** * Returns snapshots of battery attribution data, one per supplied query. * Returns true if the last update was too long ago for the tolerances specified * by the supplied queries. */ public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) { // TODO(b/174186345): instead of BatteryStatsHelper, use PowerCalculators directly. final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(mContext, false /* collectBatteryBroadcast */); batteryStatsHelper.create((Bundle) null); final List<UserHandle> users = new ArrayList<>(); for (int i = 0; i < queries.size(); i++) { public boolean shouldUpdateStats(List<BatteryUsageStatsQuery> queries, long lastUpdateTimeStampMs) { long allowableStatsAge = Long.MAX_VALUE; for (int i = queries.size() - 1; i >= 0; i--) { BatteryUsageStatsQuery query = queries.get(i); for (int userId : query.getUserIds()) { UserHandle userHandle = UserHandle.of(userId); if (!users.contains(userHandle)) { users.add(userHandle); } allowableStatsAge = Math.min(allowableStatsAge, query.getMaxStatsAge()); } return mStats.mClocks.elapsedRealtime() - lastUpdateTimeStampMs > allowableStatsAge; } batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, users); /** * Returns snapshots of battery attribution data, one per supplied query. */ public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) { ArrayList<BatteryUsageStats> results = new ArrayList<>(queries.size()); synchronized (mStats) { mStats.prepareForDumpLocked(); for (int i = 0; i < queries.size(); i++) { results.add(getBatteryUsageStats(queries.get(i))); } } return results; } Loading core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +18 −0 Original line number Diff line number Diff line Loading @@ -158,4 +158,22 @@ public class BatteryUsageStatsProviderTest { assertThat(item.time).isEqualTo(elapsedTimeMs); } @Test public void shouldUpdateStats() { Context context = InstrumentationRegistry.getContext(); BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, mStatsRule.getBatteryStats()); final List<BatteryUsageStatsQuery> queries = List.of( new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(1000).build(), new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(2000).build() ); mStatsRule.setTime(10500, 0); assertThat(provider.shouldUpdateStats(queries, 10000)).isFalse(); mStatsRule.setTime(11500, 0); assertThat(provider.shouldUpdateStats(queries, 10000)).isTrue(); } } services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +4 −2 Original line number Diff line number Diff line Loading @@ -487,10 +487,12 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { Slog.wtf(TAG, "Error updating external stats: ", e); } if ((updateFlags & UPDATE_ALL) == UPDATE_ALL) { synchronized (BatteryExternalStatsWorker.this) { mLastCollectionTimeStamp = SystemClock.elapsedRealtime(); } } } }; private final Runnable mWriteTask = new Runnable() { Loading Loading
core/java/android/os/BatteryUsageStatsQuery.java +24 −0 Original line number Diff line number Diff line Loading @@ -60,14 +60,18 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 2; private static final long DEFAULT_MAX_STATS_AGE_MS = 5 * 60 * 1000; private final int mFlags; @NonNull private final int[] mUserIds; private final long mMaxStatsAgeMs; private BatteryUsageStatsQuery(@NonNull Builder builder) { mFlags = builder.mFlags; mUserIds = builder.mUserIds != null ? builder.mUserIds.toArray() : new int[]{UserHandle.USER_ALL}; mMaxStatsAgeMs = builder.mMaxStatsAgeMs; } @BatteryUsageStatsFlags Loading @@ -94,10 +98,19 @@ public final class BatteryUsageStatsQuery implements Parcelable { return (mFlags & FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL) != 0; } /** * Returns the client's tolerance for stale battery stats. The data is allowed to be up to * this many milliseconds out-of-date. */ public long getMaxStatsAge() { return mMaxStatsAgeMs; } private BatteryUsageStatsQuery(Parcel in) { mFlags = in.readInt(); mUserIds = new int[in.readInt()]; in.readIntArray(mUserIds); mMaxStatsAgeMs = in.readLong(); } @Override Loading @@ -105,6 +118,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { dest.writeInt(mFlags); dest.writeInt(mUserIds.length); dest.writeIntArray(mUserIds); dest.writeLong(mMaxStatsAgeMs); } @Override Loading Loading @@ -132,6 +146,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { public static final class Builder { private int mFlags; private IntArray mUserIds; private long mMaxStatsAgeMs = DEFAULT_MAX_STATS_AGE_MS; /** * Builds a read-only BatteryUsageStatsQuery object. Loading Loading @@ -170,5 +185,14 @@ public final class BatteryUsageStatsQuery implements Parcelable { mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL; return this; } /** * Set the client's tolerance for stale battery stats. The data may be up to * this many milliseconds out-of-date. */ public Builder setMaxStatsAgeMs(long maxStatsAgeMs) { mMaxStatsAgeMs = maxStatsAgeMs; return this; } } }
core/java/com/android/internal/os/BatteryStatsImpl.java +2 −0 Original line number Diff line number Diff line Loading @@ -16525,6 +16525,8 @@ public class BatteryStatsImpl extends BatteryStats { // Pull the clock time. This may update the time and make a new history entry // if we had originally pulled a time before the RTC was set. getStartClockTime(); updateSystemServiceCallStats(); } public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
core/java/com/android/internal/os/BatteryUsageStatsProvider.java +20 −20 Original line number Diff line number Diff line Loading @@ -21,9 +21,7 @@ import android.hardware.SensorManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Bundle; import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -88,30 +86,32 @@ public class BatteryUsageStatsProvider { } /** * Returns snapshots of battery attribution data, one per supplied query. * Returns true if the last update was too long ago for the tolerances specified * by the supplied queries. */ public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) { // TODO(b/174186345): instead of BatteryStatsHelper, use PowerCalculators directly. final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(mContext, false /* collectBatteryBroadcast */); batteryStatsHelper.create((Bundle) null); final List<UserHandle> users = new ArrayList<>(); for (int i = 0; i < queries.size(); i++) { public boolean shouldUpdateStats(List<BatteryUsageStatsQuery> queries, long lastUpdateTimeStampMs) { long allowableStatsAge = Long.MAX_VALUE; for (int i = queries.size() - 1; i >= 0; i--) { BatteryUsageStatsQuery query = queries.get(i); for (int userId : query.getUserIds()) { UserHandle userHandle = UserHandle.of(userId); if (!users.contains(userHandle)) { users.add(userHandle); } allowableStatsAge = Math.min(allowableStatsAge, query.getMaxStatsAge()); } return mStats.mClocks.elapsedRealtime() - lastUpdateTimeStampMs > allowableStatsAge; } batteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, users); /** * Returns snapshots of battery attribution data, one per supplied query. */ public List<BatteryUsageStats> getBatteryUsageStats(List<BatteryUsageStatsQuery> queries) { ArrayList<BatteryUsageStats> results = new ArrayList<>(queries.size()); synchronized (mStats) { mStats.prepareForDumpLocked(); for (int i = 0; i < queries.size(); i++) { results.add(getBatteryUsageStats(queries.get(i))); } } return results; } Loading
core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +18 −0 Original line number Diff line number Diff line Loading @@ -158,4 +158,22 @@ public class BatteryUsageStatsProviderTest { assertThat(item.time).isEqualTo(elapsedTimeMs); } @Test public void shouldUpdateStats() { Context context = InstrumentationRegistry.getContext(); BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, mStatsRule.getBatteryStats()); final List<BatteryUsageStatsQuery> queries = List.of( new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(1000).build(), new BatteryUsageStatsQuery.Builder().setMaxStatsAgeMs(2000).build() ); mStatsRule.setTime(10500, 0); assertThat(provider.shouldUpdateStats(queries, 10000)).isFalse(); mStatsRule.setTime(11500, 0); assertThat(provider.shouldUpdateStats(queries, 10000)).isTrue(); } }
services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +4 −2 Original line number Diff line number Diff line Loading @@ -487,10 +487,12 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { Slog.wtf(TAG, "Error updating external stats: ", e); } if ((updateFlags & UPDATE_ALL) == UPDATE_ALL) { synchronized (BatteryExternalStatsWorker.this) { mLastCollectionTimeStamp = SystemClock.elapsedRealtime(); } } } }; private final Runnable mWriteTask = new Runnable() { Loading