Loading core/java/android/os/BatteryUsageStats.java +73 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import android.annotation.NonNull; import android.util.Range; import android.util.SparseArray; import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.BatteryStatsHistoryIterator; import java.util.ArrayList; import java.util.List; Loading @@ -37,12 +40,16 @@ public final class BatteryUsageStats implements Parcelable { private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers; private final ArrayList<SystemBatteryConsumer> mSystemBatteryConsumers; private final ArrayList<UserBatteryConsumer> mUserBatteryConsumers; private final Parcel mHistoryBuffer; private final List<BatteryStats.HistoryTag> mHistoryTagPool; private BatteryUsageStats(@NonNull Builder builder) { mStatsStartRealtimeMs = builder.mStatsStartRealtimeMs; mDischargePercentage = builder.mDischargePercentage; mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah; mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah; mHistoryBuffer = builder.mHistoryBuffer; mHistoryTagPool = builder.mHistoryTagPool; double totalPower = 0; Loading Loading @@ -125,6 +132,19 @@ public final class BatteryUsageStats implements Parcelable { return mUserBatteryConsumers; } /** * Returns an iterator for {@link android.os.BatteryStats.HistoryItem}'s. */ @NonNull public BatteryStatsHistoryIterator iterateBatteryStatsHistory() { if (mHistoryBuffer == null) { throw new IllegalStateException( "Battery history was not requested in the BatteryUsageStatsQuery"); } return new BatteryStatsHistoryIterator(new BatteryStatsHistory(mHistoryBuffer), mHistoryTagPool); } @Override public int describeContents() { return 0; Loading @@ -142,6 +162,29 @@ public final class BatteryUsageStats implements Parcelable { source.readParcelableList(mSystemBatteryConsumers, getClass().getClassLoader()); mUserBatteryConsumers = new ArrayList<>(); source.readParcelableList(mUserBatteryConsumers, getClass().getClassLoader()); if (source.readBoolean()) { mHistoryBuffer = Parcel.obtain(); mHistoryBuffer.setDataSize(0); mHistoryBuffer.setDataPosition(0); int historyBufferSize = source.readInt(); int curPos = source.dataPosition(); mHistoryBuffer.appendFrom(source, curPos, historyBufferSize); source.setDataPosition(curPos + historyBufferSize); int historyTagCount = source.readInt(); mHistoryTagPool = new ArrayList<>(historyTagCount); for (int i = 0; i < historyTagCount; i++) { BatteryStats.HistoryTag tag = new BatteryStats.HistoryTag(); tag.string = source.readString(); tag.uid = source.readInt(); tag.poolIdx = source.readInt(); mHistoryTagPool.add(tag); } } else { mHistoryBuffer = null; mHistoryTagPool = null; } } @Override Loading @@ -154,6 +197,23 @@ public final class BatteryUsageStats implements Parcelable { dest.writeParcelableList(mUidBatteryConsumers, flags); dest.writeParcelableList(mSystemBatteryConsumers, flags); dest.writeParcelableList(mUserBatteryConsumers, flags); if (mHistoryBuffer != null) { dest.writeBoolean(true); final int historyBufferSize = mHistoryBuffer.dataSize(); dest.writeInt(historyBufferSize); dest.appendFrom(mHistoryBuffer, 0, historyBufferSize); dest.writeInt(mHistoryTagPool.size()); for (int i = mHistoryTagPool.size() - 1; i >= 0; i--) { final BatteryStats.HistoryTag tag = mHistoryTagPool.get(i); dest.writeString(tag.string); dest.writeInt(tag.uid); dest.writeInt(tag.poolIdx); } } else { dest.writeBoolean(false); } } @NonNull Loading Loading @@ -183,6 +243,8 @@ public final class BatteryUsageStats implements Parcelable { new SparseArray<>(); private final SparseArray<UserBatteryConsumer.Builder> mUserBatteryConsumerBuilders = new SparseArray<>(); private Parcel mHistoryBuffer; private List<BatteryStats.HistoryTag> mHistoryTagPool; public Builder(int customPowerComponentCount, int customTimeComponentCount) { mCustomPowerComponentCount = customPowerComponentCount; Loading Loading @@ -226,6 +288,17 @@ public final class BatteryUsageStats implements Parcelable { return this; } /** * Sets the parceled recent history. */ @NonNull public Builder setBatteryHistory(Parcel historyBuffer, List<BatteryStats.HistoryTag> historyTagPool) { mHistoryBuffer = historyBuffer; mHistoryTagPool = historyTagPool; return this; } /** * Creates or returns a exiting UidBatteryConsumer, which represents battery attribution * data for an individual UID. Loading core/java/android/os/BatteryUsageStatsQuery.java +10 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ @IntDef(flag = true, prefix = { "FLAG_BATTERY_USAGE_STATS_" }, value = { FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL, FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY, }) @Retention(RetentionPolicy.SOURCE) public @interface BatteryUsageStatsFlags {} Loading @@ -53,6 +54,12 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ public static final int FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL = 1; /** * Indicates that battery history should be included in the BatteryUsageStats. * @hide */ public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 2; private final int mFlags; @NonNull private final int[] mUserIds; Loading Loading @@ -146,10 +153,10 @@ public final class BatteryUsageStatsQuery implements Parcelable { } /** * Sets flags to modify the behavior of {@link BatteryStatsManager#getBatteryUsageStats}. * Requests that battery history be included in the BatteryUsageStats. */ public Builder setFlags(@BatteryUsageStatsFlags int flags) { mFlags = flags; public Builder includeBatteryHistory() { mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY; return this; } Loading core/java/com/android/internal/os/BatteryStatsHistoryIterator.java +1 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public class BatteryStatsHistoryIterator { private final String[] mReadHistoryStrings; private final int[] mReadHistoryUids; BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history, public BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history, @NonNull List<BatteryStats.HistoryTag> historyTagPool) { mBatteryStatsHistory = history; Loading core/java/com/android/internal/os/BatteryUsageStatsProvider.java +15 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Uses accumulated battery stats data and PowerCalculators to produce power Loading Loading @@ -152,6 +153,20 @@ public class BatteryUsageStatsProvider { query); } if ((query.getFlags() & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY) != 0) { ArrayList<BatteryStats.HistoryTag> tags = new ArrayList<>( mStats.mHistoryTagPool.size()); for (Map.Entry<BatteryStats.HistoryTag, Integer> entry : mStats.mHistoryTagPool.entrySet()) { final BatteryStats.HistoryTag tag = entry.getKey(); tag.poolIdx = entry.getValue(); tags.add(tag); } batteryUsageStatsBuilder.setBatteryHistory(mStats.mHistoryBuffer, tags); } return batteryUsageStatsBuilder.build(); } Loading core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +85 −0 Original line number Diff line number Diff line Loading @@ -20,8 +20,11 @@ import static com.google.common.truth.Truth.assertThat; import android.app.ActivityManager; import android.content.Context; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Parcel; import android.os.Process; import android.os.UidBatteryConsumer; Loading Loading @@ -73,4 +76,86 @@ public class BatteryUsageStatsProviderTest { assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND)) .isEqualTo(10 * MINUTE_IN_MS); } @Test public void testWriteAndReadHistory() { MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); batteryStats.setRecordAllHistoryLocked(true); batteryStats.forceRecordAllHistory(); batteryStats.setNoAutoReset(true); batteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, /* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0, 1_000_000, 1_000_000, 1_000_000); batteryStats.noteAlarmStartLocked("foo", null, APP_UID, 3_000_000, 2_000_000); batteryStats.noteAlarmFinishLocked("foo", null, APP_UID, 3_001_000, 2_001_000); Context context = InstrumentationRegistry.getContext(); BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats); final BatteryUsageStats batteryUsageStats = provider.getBatteryUsageStats( new BatteryUsageStatsQuery.Builder().includeBatteryHistory().build()); Parcel in = Parcel.obtain(); batteryUsageStats.writeToParcel(in, 0); final byte[] bytes = in.marshall(); Parcel out = Parcel.obtain(); out.unmarshall(bytes, 0, bytes.length); out.setDataPosition(0); BatteryUsageStats unparceled = BatteryUsageStats.CREATOR.createFromParcel(out); final BatteryStatsHistoryIterator iterator = unparceled.iterateBatteryStatsHistory(); BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_RESET, BatteryStats.HistoryItem.EVENT_NONE, null, 0, 3_600_000, 90, 1_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, null, 0, 3_600_000, 90, 1_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, null, 0, 3_600_000, 90, 2_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START, "foo", APP_UID, 3_600_000, 90, 3_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_FINISH, "foo", APP_UID, 3_600_000, 90, 3_001_000); assertThat(iterator.next(item)).isFalse(); } private void assertHistoryItem(BatteryStats.HistoryItem item, int command, int eventCode, String tag, int uid, int batteryChargeUah, int batteryLevel, long elapsedTimeMs) { assertThat(item.cmd).isEqualTo(command); assertThat(item.eventCode).isEqualTo(eventCode); if (tag == null) { assertThat(item.eventTag).isNull(); } else { assertThat(item.eventTag.string).isEqualTo(tag); assertThat(item.eventTag.uid).isEqualTo(uid); } assertThat(item.batteryChargeUah).isEqualTo(batteryChargeUah); assertThat(item.batteryLevel).isEqualTo(batteryLevel); assertThat(item.time).isEqualTo(elapsedTimeMs); } } Loading
core/java/android/os/BatteryUsageStats.java +73 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import android.annotation.NonNull; import android.util.Range; import android.util.SparseArray; import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.BatteryStatsHistoryIterator; import java.util.ArrayList; import java.util.List; Loading @@ -37,12 +40,16 @@ public final class BatteryUsageStats implements Parcelable { private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers; private final ArrayList<SystemBatteryConsumer> mSystemBatteryConsumers; private final ArrayList<UserBatteryConsumer> mUserBatteryConsumers; private final Parcel mHistoryBuffer; private final List<BatteryStats.HistoryTag> mHistoryTagPool; private BatteryUsageStats(@NonNull Builder builder) { mStatsStartRealtimeMs = builder.mStatsStartRealtimeMs; mDischargePercentage = builder.mDischargePercentage; mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah; mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah; mHistoryBuffer = builder.mHistoryBuffer; mHistoryTagPool = builder.mHistoryTagPool; double totalPower = 0; Loading Loading @@ -125,6 +132,19 @@ public final class BatteryUsageStats implements Parcelable { return mUserBatteryConsumers; } /** * Returns an iterator for {@link android.os.BatteryStats.HistoryItem}'s. */ @NonNull public BatteryStatsHistoryIterator iterateBatteryStatsHistory() { if (mHistoryBuffer == null) { throw new IllegalStateException( "Battery history was not requested in the BatteryUsageStatsQuery"); } return new BatteryStatsHistoryIterator(new BatteryStatsHistory(mHistoryBuffer), mHistoryTagPool); } @Override public int describeContents() { return 0; Loading @@ -142,6 +162,29 @@ public final class BatteryUsageStats implements Parcelable { source.readParcelableList(mSystemBatteryConsumers, getClass().getClassLoader()); mUserBatteryConsumers = new ArrayList<>(); source.readParcelableList(mUserBatteryConsumers, getClass().getClassLoader()); if (source.readBoolean()) { mHistoryBuffer = Parcel.obtain(); mHistoryBuffer.setDataSize(0); mHistoryBuffer.setDataPosition(0); int historyBufferSize = source.readInt(); int curPos = source.dataPosition(); mHistoryBuffer.appendFrom(source, curPos, historyBufferSize); source.setDataPosition(curPos + historyBufferSize); int historyTagCount = source.readInt(); mHistoryTagPool = new ArrayList<>(historyTagCount); for (int i = 0; i < historyTagCount; i++) { BatteryStats.HistoryTag tag = new BatteryStats.HistoryTag(); tag.string = source.readString(); tag.uid = source.readInt(); tag.poolIdx = source.readInt(); mHistoryTagPool.add(tag); } } else { mHistoryBuffer = null; mHistoryTagPool = null; } } @Override Loading @@ -154,6 +197,23 @@ public final class BatteryUsageStats implements Parcelable { dest.writeParcelableList(mUidBatteryConsumers, flags); dest.writeParcelableList(mSystemBatteryConsumers, flags); dest.writeParcelableList(mUserBatteryConsumers, flags); if (mHistoryBuffer != null) { dest.writeBoolean(true); final int historyBufferSize = mHistoryBuffer.dataSize(); dest.writeInt(historyBufferSize); dest.appendFrom(mHistoryBuffer, 0, historyBufferSize); dest.writeInt(mHistoryTagPool.size()); for (int i = mHistoryTagPool.size() - 1; i >= 0; i--) { final BatteryStats.HistoryTag tag = mHistoryTagPool.get(i); dest.writeString(tag.string); dest.writeInt(tag.uid); dest.writeInt(tag.poolIdx); } } else { dest.writeBoolean(false); } } @NonNull Loading Loading @@ -183,6 +243,8 @@ public final class BatteryUsageStats implements Parcelable { new SparseArray<>(); private final SparseArray<UserBatteryConsumer.Builder> mUserBatteryConsumerBuilders = new SparseArray<>(); private Parcel mHistoryBuffer; private List<BatteryStats.HistoryTag> mHistoryTagPool; public Builder(int customPowerComponentCount, int customTimeComponentCount) { mCustomPowerComponentCount = customPowerComponentCount; Loading Loading @@ -226,6 +288,17 @@ public final class BatteryUsageStats implements Parcelable { return this; } /** * Sets the parceled recent history. */ @NonNull public Builder setBatteryHistory(Parcel historyBuffer, List<BatteryStats.HistoryTag> historyTagPool) { mHistoryBuffer = historyBuffer; mHistoryTagPool = historyTagPool; return this; } /** * Creates or returns a exiting UidBatteryConsumer, which represents battery attribution * data for an individual UID. Loading
core/java/android/os/BatteryUsageStatsQuery.java +10 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ @IntDef(flag = true, prefix = { "FLAG_BATTERY_USAGE_STATS_" }, value = { FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL, FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY, }) @Retention(RetentionPolicy.SOURCE) public @interface BatteryUsageStatsFlags {} Loading @@ -53,6 +54,12 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ public static final int FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL = 1; /** * Indicates that battery history should be included in the BatteryUsageStats. * @hide */ public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 2; private final int mFlags; @NonNull private final int[] mUserIds; Loading Loading @@ -146,10 +153,10 @@ public final class BatteryUsageStatsQuery implements Parcelable { } /** * Sets flags to modify the behavior of {@link BatteryStatsManager#getBatteryUsageStats}. * Requests that battery history be included in the BatteryUsageStats. */ public Builder setFlags(@BatteryUsageStatsFlags int flags) { mFlags = flags; public Builder includeBatteryHistory() { mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY; return this; } Loading
core/java/com/android/internal/os/BatteryStatsHistoryIterator.java +1 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public class BatteryStatsHistoryIterator { private final String[] mReadHistoryStrings; private final int[] mReadHistoryUids; BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history, public BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history, @NonNull List<BatteryStats.HistoryTag> historyTagPool) { mBatteryStatsHistory = history; Loading
core/java/com/android/internal/os/BatteryUsageStatsProvider.java +15 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Uses accumulated battery stats data and PowerCalculators to produce power Loading Loading @@ -152,6 +153,20 @@ public class BatteryUsageStatsProvider { query); } if ((query.getFlags() & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY) != 0) { ArrayList<BatteryStats.HistoryTag> tags = new ArrayList<>( mStats.mHistoryTagPool.size()); for (Map.Entry<BatteryStats.HistoryTag, Integer> entry : mStats.mHistoryTagPool.entrySet()) { final BatteryStats.HistoryTag tag = entry.getKey(); tag.poolIdx = entry.getValue(); tags.add(tag); } batteryUsageStatsBuilder.setBatteryHistory(mStats.mHistoryBuffer, tags); } return batteryUsageStatsBuilder.build(); } Loading
core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +85 −0 Original line number Diff line number Diff line Loading @@ -20,8 +20,11 @@ import static com.google.common.truth.Truth.assertThat; import android.app.ActivityManager; import android.content.Context; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Parcel; import android.os.Process; import android.os.UidBatteryConsumer; Loading Loading @@ -73,4 +76,86 @@ public class BatteryUsageStatsProviderTest { assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND)) .isEqualTo(10 * MINUTE_IN_MS); } @Test public void testWriteAndReadHistory() { MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); batteryStats.setRecordAllHistoryLocked(true); batteryStats.forceRecordAllHistory(); batteryStats.setNoAutoReset(true); batteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, /* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0, 1_000_000, 1_000_000, 1_000_000); batteryStats.noteAlarmStartLocked("foo", null, APP_UID, 3_000_000, 2_000_000); batteryStats.noteAlarmFinishLocked("foo", null, APP_UID, 3_001_000, 2_001_000); Context context = InstrumentationRegistry.getContext(); BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats); final BatteryUsageStats batteryUsageStats = provider.getBatteryUsageStats( new BatteryUsageStatsQuery.Builder().includeBatteryHistory().build()); Parcel in = Parcel.obtain(); batteryUsageStats.writeToParcel(in, 0); final byte[] bytes = in.marshall(); Parcel out = Parcel.obtain(); out.unmarshall(bytes, 0, bytes.length); out.setDataPosition(0); BatteryUsageStats unparceled = BatteryUsageStats.CREATOR.createFromParcel(out); final BatteryStatsHistoryIterator iterator = unparceled.iterateBatteryStatsHistory(); BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_RESET, BatteryStats.HistoryItem.EVENT_NONE, null, 0, 3_600_000, 90, 1_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, null, 0, 3_600_000, 90, 1_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, null, 0, 3_600_000, 90, 2_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START, "foo", APP_UID, 3_600_000, 90, 3_000_000); assertThat(iterator.next(item)).isTrue(); assertHistoryItem(item, BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_FINISH, "foo", APP_UID, 3_600_000, 90, 3_001_000); assertThat(iterator.next(item)).isFalse(); } private void assertHistoryItem(BatteryStats.HistoryItem item, int command, int eventCode, String tag, int uid, int batteryChargeUah, int batteryLevel, long elapsedTimeMs) { assertThat(item.cmd).isEqualTo(command); assertThat(item.eventCode).isEqualTo(eventCode); if (tag == null) { assertThat(item.eventTag).isNull(); } else { assertThat(item.eventTag.string).isEqualTo(tag); assertThat(item.eventTag.uid).isEqualTo(uid); } assertThat(item.batteryChargeUah).isEqualTo(batteryChargeUah); assertThat(item.batteryLevel).isEqualTo(batteryLevel); assertThat(item.time).isEqualTo(elapsedTimeMs); } }