diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0cd0c8661ab..795c118ca1b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4987,6 +4987,8 @@
Background: %s
Battery usage data will be available in a few hours once fully charged
+
+ now
Battery usage chart
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
index 7e1bb381224..707c5b2fa94 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
@@ -47,6 +47,8 @@ import com.android.settingslib.core.lifecycle.events.OnDestroy;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
+import com.google.common.base.Objects;
+
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
@@ -238,7 +240,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
hourlyBatteryLevelsPerDay.getLevels(),
hourlyBatteryLevelsPerDay.getTimestamps(),
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS,
- mHourlyChartLabelTextGenerator));
+ mHourlyChartLabelTextGenerator.setLatestTimestamp(getLast(getLast(
+ batteryLevelData.getHourlyBatteryLevelsPerDay()).getTimestamps()))));
}
refreshUi();
}
@@ -514,6 +517,13 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
return allBatteryDiffData == null ? null : allBatteryDiffData.getAppDiffEntryList();
}
+ private static T getLast(List list) {
+ if (list == null || list.isEmpty()) {
+ return null;
+ }
+ return list.get(list.size() - 1);
+ }
+
/** Used for {@link AppBatteryPreferenceController}. */
public static BatteryDiffEntry getAppBatteryUsageData(
Context context, String packageName, int userId) {
@@ -553,18 +563,33 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
private final class HourlyChartLabelTextGenerator implements
BatteryChartViewModel.LabelTextGenerator {
+ private Long mLatestTimestamp;
+
@Override
public String generateText(List timestamps, int index) {
+ if (Objects.equal(timestamps.get(index), mLatestTimestamp)) {
+ // Replaces the latest timestamp text to "now".
+ return mContext.getString(R.string.battery_usage_chart_label_now);
+ }
return ConvertUtils.utcToLocalTimeHour(mContext, timestamps.get(index),
mIs24HourFormat);
}
@Override
public String generateFullText(List timestamps, int index) {
+ if (Objects.equal(timestamps.get(index), mLatestTimestamp)) {
+ // Replaces the latest timestamp text to "now".
+ return mContext.getString(R.string.battery_usage_chart_label_now);
+ }
return index == timestamps.size() - 1
? generateText(timestamps, index)
: String.format("%s%s%s", generateText(timestamps, index),
- mIs24HourFormat ? "-" : " - ", generateText(timestamps, index + 1));
+ mIs24HourFormat ? "-" : " - ", generateText(timestamps, index + 1));
+ }
+
+ public HourlyChartLabelTextGenerator setLatestTimestamp(Long latestTimestamp) {
+ this.mLatestTimestamp = latestTimestamp;
+ return this;
}
}
}
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
index 282781893cc..b510e5b19e2 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
@@ -21,6 +21,7 @@ import static com.android.settings.fuelgauge.batteryusage.ConvertUtils.utcToLoca
import android.app.settings.SettingsEnums;
import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.BatteryConsumer;
@@ -86,6 +87,12 @@ public final class DataProcessor {
static final double PERCENTAGE_OF_TOTAL_THRESHOLD = 1f;
@VisibleForTesting
static final int SELECTED_INDEX_ALL = BatteryChartViewModel.SELECTED_INDEX_ALL;
+ @VisibleForTesting
+ static final String CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER =
+ "CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER";
+
+ @VisibleForTesting
+ static long sFakeCurrentTimeMillis = 0;
/** A callback listener when battery usage loading async task is executed. */
public interface UsageMapAsyncResponse {
@@ -239,11 +246,12 @@ public final class DataProcessor {
return resultMap;
}
Collections.sort(rawTimestampList);
- final List expectedTimestampList = getTimestampSlots(rawTimestampList);
+ final long currentTime = getCurrentTimeMillis();
+ final List expectedTimestampList = getTimestampSlots(rawTimestampList, currentTime);
final boolean isFromFullCharge =
isFromFullCharge(batteryHistoryMap.get(rawTimestampList.get(0)));
interpolateHistory(
- context, rawTimestampList, expectedTimestampList, isFromFullCharge,
+ context, rawTimestampList, expectedTimestampList, currentTime, isFromFullCharge,
batteryHistoryMap, resultMap);
Log.d(TAG, String.format("getHistoryMapWithExpectedTimestamps() size=%d in %d/ms",
resultMap.size(), (System.currentTimeMillis() - startTime)));
@@ -278,19 +286,16 @@ public final class DataProcessor {
* between start and end two even hour values.
*/
@VisibleForTesting
- static List getTimestampSlots(final List rawTimestampList) {
+ static List getTimestampSlots(final List rawTimestampList, final long currentTime) {
final List timestampSlots = new ArrayList<>();
- final int rawTimestampListSize = rawTimestampList.size();
- // If timestamp number is smaller than 2, the following computation is not necessary.
- if (rawTimestampListSize < MIN_TIMESTAMP_DATA_SIZE) {
+ if (rawTimestampList.isEmpty()) {
return timestampSlots;
}
final long rawStartTimestamp = rawTimestampList.get(0);
- final long rawEndTimestamp = rawTimestampList.get(rawTimestampListSize - 1);
// No matter the start is from last full charge or 6 days ago, use the nearest even hour.
final long startTimestamp = getNearestEvenHourTimestamp(rawStartTimestamp);
- // Use the even hour before the raw end timestamp as the end.
- final long endTimestamp = getLastEvenHourBeforeTimestamp(rawEndTimestamp);
+ // Use the first even hour after the current time as the end.
+ final long endTimestamp = getFirstEvenHourAfterTimestamp(currentTime);
// If the start timestamp is later or equal the end one, return the empty list.
if (startTimestamp >= endTimestamp) {
return timestampSlots;
@@ -451,10 +456,7 @@ public final class DataProcessor {
@Nullable
static BatteryDiffData generateBatteryDiffData(
final Context context,
- @Nullable final List batteryEntryList,
- final BatteryUsageStats batteryUsageStats) {
- final List batteryHistEntryList =
- convertToBatteryHistEntry(batteryEntryList, batteryUsageStats);
+ final List batteryHistEntryList) {
if (batteryHistEntryList == null || batteryHistEntryList.isEmpty()) {
Log.w(TAG, "batteryHistEntryList is null or empty in generateBatteryDiffData()");
return null;
@@ -531,7 +533,7 @@ public final class DataProcessor {
final Map allUsageMap = new HashMap<>();
// Always construct the map whether the value is null or not.
allUsageMap.put(SELECTED_INDEX_ALL,
- getBatteryDiffDataFromBatteryStatsService(context));
+ generateBatteryDiffData(context, getBatteryHistListFromFromStatsService(context)));
resultMap.put(SELECTED_INDEX_ALL, allUsageMap);
// Compute the apps number before purge. Must put before purgeLowPercentageAndFakeData.
@@ -545,24 +547,33 @@ public final class DataProcessor {
}
@Nullable
- private static BatteryDiffData getBatteryDiffDataFromBatteryStatsService(
+ private static List getBatteryHistListFromFromStatsService(
final Context context) {
- BatteryDiffData batteryDiffData = null;
+ List batteryHistEntryList = null;
try {
final BatteryUsageStats batteryUsageStats = getBatteryUsageStats(context);
final List batteryEntryList =
generateBatteryEntryListFromBatteryUsageStats(context, batteryUsageStats);
- batteryDiffData = generateBatteryDiffData(context, batteryEntryList, batteryUsageStats);
+ batteryHistEntryList = convertToBatteryHistEntry(batteryEntryList, batteryUsageStats);
closeBatteryUsageStats(batteryUsageStats);
} catch (RuntimeException e) {
Log.e(TAG, "load batteryUsageStats:" + e);
}
- return batteryDiffData;
+ return batteryHistEntryList;
}
+ private static Map getCurrentBatteryHistoryMapFromStatsService(
+ final Context context) {
+ final List batteryHistEntryList =
+ getBatteryHistListFromFromStatsService(context);
+ return batteryHistEntryList == null ? new HashMap<>()
+ : batteryHistEntryList.stream().collect(Collectors.toMap(e -> e.getKey(), e -> e));
+ }
+
+ @VisibleForTesting
@Nullable
- private static List convertToBatteryHistEntry(
+ static List convertToBatteryHistEntry(
@Nullable final List batteryEntryList,
final BatteryUsageStats batteryUsageStats) {
if (batteryEntryList == null || batteryEntryList.isEmpty()) {
@@ -591,6 +602,7 @@ public final class DataProcessor {
Context context,
final List rawTimestampList,
final List expectedTimestampSlots,
+ final long currentTime,
final boolean isFromFullCharge,
final Map> batteryHistoryMap,
final Map> resultMap) {
@@ -611,6 +623,17 @@ public final class DataProcessor {
final int expectedTimestampSlotsSize = expectedTimestampSlots.size();
for (int index = startIndex; index < expectedTimestampSlotsSize; index++) {
final long currentSlot = expectedTimestampSlots.get(index);
+ if (currentSlot > currentTime) {
+ // The slot timestamp is greater than the current time. Puts a placeholder first,
+ // then in the async task, loads the real time battery usage data from the battery
+ // stats service.
+ // If current time is odd hour, one placeholder is added. If the current hour is
+ // even hour, two placeholders are added. This is because the method
+ // insertHourlyUsageDiffDataPerSlot() requires continuing three hours data.
+ resultMap.put(currentSlot,
+ Map.of(CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER, EMPTY_BATTERY_HIST_ENTRY));
+ continue;
+ }
final boolean isStartOrEnd = index == 0 || index == expectedTimestampSlotsSize - 1;
interpolateHistoryForSlot(
context, currentSlot, rawTimestampList, batteryHistoryMap, resultMap,
@@ -732,6 +755,13 @@ public final class DataProcessor {
return getEvenHourTimestamp(rawTimestamp, /*addHourOfDay*/ 1);
}
+ /**
+ * @return Returns the fist even hour timestamp after the given timestamp.
+ */
+ private static long getFirstEvenHourAfterTimestamp(long rawTimestamp) {
+ return getLastEvenHourBeforeTimestamp(rawTimestamp + DateUtils.HOUR_IN_MILLIS * 2);
+ }
+
/**
* @return Returns the last even hour timestamp before the given timestamp.
*/
@@ -809,6 +839,12 @@ public final class DataProcessor {
+ utcToLocalTime(context, timestamp));
return null;
}
+ // The current time battery history hasn't been loaded yet, returns the current battery
+ // level.
+ if (entryMap.containsKey(CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER)) {
+ final Intent intent = BatteryUtils.getBatteryIntent(context);
+ return BatteryStatus.getBatteryLevel(intent);
+ }
// Averages the battery level in each time slot to avoid corner conditions.
float batteryLevelCounter = 0;
for (BatteryHistEntry entry : entryMap.values()) {
@@ -1394,6 +1430,10 @@ public final class DataProcessor {
return batteryDiffEntry;
}
+ private static long getCurrentTimeMillis() {
+ return sFakeCurrentTimeMillis > 0 ? sFakeCurrentTimeMillis : System.currentTimeMillis();
+ }
+
private static void logAppCountMetrics(
Context context, final int countOfAppBeforePurge, final int countOfAppAfterPurge) {
context = context.getApplicationContext();
@@ -1465,6 +1505,17 @@ public final class DataProcessor {
return null;
}
final long startTime = System.currentTimeMillis();
+ // Loads the current battery usage data from the battery stats service and replaces the
+ // placeholder in mBatteryHistoryMap.
+ Map currentBatteryHistoryMap =
+ getCurrentBatteryHistoryMapFromStatsService(mApplicationContext);
+ for (Map.Entry> mapEntry
+ : mBatteryHistoryMap.entrySet()) {
+ if (mapEntry.getValue().containsKey(CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER)) {
+ mapEntry.setValue(currentBatteryHistoryMap);
+ }
+ }
+
final Map> batteryUsageMap =
getBatteryUsageMap(
mApplicationContext, mHourlyBatteryLevelsPerDay, mBatteryHistoryMap);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
index 42eb1c080ba..95e3bad12b5 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerTest.java
@@ -19,7 +19,9 @@ package com.android.settings.fuelgauge.batteryusage;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
@@ -30,7 +32,9 @@ import static org.mockito.Mockito.verify;
import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Resources;
+import android.os.BatteryManager;
import android.os.Bundle;
import android.os.LocaleList;
import android.text.format.DateUtils;
@@ -57,6 +61,8 @@ import java.util.TimeZone;
@RunWith(RobolectricTestRunner.class)
public final class BatteryChartPreferenceControllerTest {
+ @Mock
+ private Intent mIntent;
@Mock
private SettingsActivity mSettingsActivity;
@Mock
@@ -90,6 +96,9 @@ public final class BatteryChartPreferenceControllerTest {
.when(mFeatureFactory.powerUsageFeatureProvider)
.getHideApplicationEntries(mContext);
doReturn(mLayoutParams).when(mDailyChartView).getLayoutParams();
+ doReturn(mIntent).when(mContext).registerReceiver(any(), any());
+ doReturn(100).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_SCALE), anyInt());
+ doReturn(66).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_LEVEL), anyInt());
setupHourlyChartViewAnimationMock();
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mPrefContext = mContext;
@@ -144,10 +153,11 @@ public final class BatteryChartPreferenceControllerTest {
// Ignore fast refresh ui from the data processor callback.
verify(mHourlyChartView, atLeast(0)).setViewModel(null);
verify(mHourlyChartView, atLeastOnce()).setViewModel(new BatteryChartViewModel(
- List.of(100, 97, 95),
+ List.of(100, 97, 95, 66),
List.of(1619251200000L /* 8 AM */,
1619258400000L /* 10 AM */,
- 1619265600000L /* 12 PM */),
+ 1619265600000L /* 12 PM */,
+ 1619272800000L /* 2 PM */),
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS,
mBatteryChartPreferenceController.mHourlyChartLabelTextGenerator));
}
@@ -159,12 +169,12 @@ public final class BatteryChartPreferenceControllerTest {
setupHourlyChartViewAnimationMock();
BatteryChartViewModel expectedDailyViewModel = new BatteryChartViewModel(
- List.of(100, 83, 59, 41),
+ List.of(100, 83, 59, 66),
// "Sat", "Sun", "Mon", "Mon"
List.of(1619251200000L /* Sat */,
1619308800000L /* Sun */,
1619395200000L /* Mon */,
- 1619460000000L /* Mon */),
+ 1619467200000L /* Mon */),
BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS,
mBatteryChartPreferenceController.mDailyChartLabelTextGenerator);
@@ -244,7 +254,7 @@ public final class BatteryChartPreferenceControllerTest {
expectedDailyViewModel.setSelectedIndex(2);
verify(mDailyChartView).setViewModel(expectedDailyViewModel);
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
- List.of(59, 57, 55, 53, 51, 49, 47, 45, 43, 41),
+ List.of(59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 66),
List.of(1619395200000L /* 12 AM */,
1619402400000L /* 2 AM */,
1619409600000L /* 4 AM */,
@@ -254,9 +264,11 @@ public final class BatteryChartPreferenceControllerTest {
1619438400000L /* 12 PM */,
1619445600000L /* 2 PM */,
1619452800000L /* 4 PM */,
- 1619460000000L /* 6 PM */),
+ 1619460000000L /* 6 PM */,
+ 1619467200000L /* 8 PM */),
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS,
mBatteryChartPreferenceController.mHourlyChartLabelTextGenerator));
+
}
@Test
@@ -364,7 +376,7 @@ public final class BatteryChartPreferenceControllerTest {
final int totalHour = BatteryChartPreferenceController.getTotalHours(batteryLevelData);
// Only calculate the even hours.
- assertThat(totalHour).isEqualTo(58);
+ assertThat(totalHour).isEqualTo(60);
}
private static Long generateTimestamp(int index) {
@@ -395,6 +407,8 @@ public final class BatteryChartPreferenceControllerTest {
entryMap.put("fake_entry_key" + index, entry);
batteryHistoryMap.put(generateTimestamp(index), entryMap);
}
+ DataProcessor.sFakeCurrentTimeMillis =
+ generateTimestamp(numOfHours - 1) + DateUtils.MINUTE_IN_MILLIS;
return batteryHistoryMap;
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
index 0926d146db9..ce6a917cab5 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
@@ -18,7 +18,10 @@ package com.android.settings.fuelgauge.batteryusage;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -27,7 +30,9 @@ import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums;
import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
import android.os.BatteryConsumer;
+import android.os.BatteryManager;
import android.os.BatteryUsageStats;
import android.text.format.DateUtils;
@@ -63,6 +68,7 @@ public class DataProcessorTest {
private MetricsFeatureProvider mMetricsFeatureProvider;
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
+ @Mock private Intent mIntent;
@Mock private BatteryUsageStats mBatteryUsageStats;
@Mock private BatteryEntry mMockBatteryEntry1;
@Mock private BatteryEntry mMockBatteryEntry2;
@@ -79,6 +85,10 @@ public class DataProcessorTest {
mFeatureFactory = FakeFeatureFactory.setupForTest();
mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider;
+
+ doReturn(mIntent).when(mContext).registerReceiver(any(), any());
+ doReturn(100).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_SCALE), anyInt());
+ doReturn(66).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_LEVEL), anyInt());
}
@Test
@@ -100,11 +110,15 @@ public class DataProcessorTest {
@Test
public void getBatteryLevelData_notEnoughData_returnNull() {
- // The timestamps are within 1 hour.
- final long[] timestamps = {1000000L, 2000000L, 3000000L};
+ // The timestamps and the current time are within half hour before an even hour.
+ final long[] timestamps = {
+ DateUtils.HOUR_IN_MILLIS * 2 - 300L,
+ DateUtils.HOUR_IN_MILLIS * 2 - 200L,
+ DateUtils.HOUR_IN_MILLIS * 2 - 100L};
final int[] levels = {100, 99, 98};
final Map> batteryHistoryMap =
createHistoryMap(timestamps, levels);
+ DataProcessor.sFakeCurrentTimeMillis = timestamps[timestamps.length - 1];
assertThat(DataProcessor.getBatteryLevelData(
mContext, /*handler=*/ null, batteryHistoryMap, /*asyncResponseDelegate=*/ null))
@@ -117,11 +131,12 @@ public class DataProcessorTest {
@Test
public void getBatteryLevelData_returnExpectedResult() {
- // Timezone GMT+8: 2022-01-01 00:00:00, 2022-01-01 01:00:00, 2022-01-01 02:00:00
- final long[] timestamps = {1640966400000L, 1640970000000L, 1640973600000L};
- final int[] levels = {100, 99, 98};
+ // Timezone GMT+8: 2022-01-01 00:00:00, 2022-01-01 01:00:00
+ final long[] timestamps = {1640966400000L, 1640970000000L};
+ final int[] levels = {100, 99};
final Map> batteryHistoryMap =
createHistoryMap(timestamps, levels);
+ DataProcessor.sFakeCurrentTimeMillis = timestamps[timestamps.length - 1];
final BatteryLevelData resultData =
DataProcessor.getBatteryLevelData(
@@ -130,8 +145,10 @@ public class DataProcessorTest {
batteryHistoryMap,
/*asyncResponseDelegate=*/ null);
- final List expectedDailyTimestamps = List.of(timestamps[0], timestamps[2]);
- final List expectedDailyLevels = List.of(levels[0], levels[2]);
+ final List expectedDailyTimestamps = List.of(
+ 1640966400000L, // 2022-01-01 00:00:00
+ 1640973600000L); // 2022-01-01 02:00:00
+ final List expectedDailyLevels = List.of(100, 66);
final List> expectedHourlyTimestamps = List.of(expectedDailyTimestamps);
final List> expectedHourlyLevels = List.of(expectedDailyLevels);
verifyExpectedBatteryLevelData(
@@ -162,6 +179,7 @@ public class DataProcessorTest {
final int[] levels = {100, 94, 90, 82, 50};
final Map> batteryHistoryMap =
createHistoryMap(timestamps, levels);
+ DataProcessor.sFakeCurrentTimeMillis = timestamps[timestamps.length - 1];
final Map> resultMap =
DataProcessor.getHistoryMapWithExpectedTimestamps(mContext, batteryHistoryMap);
@@ -172,14 +190,20 @@ public class DataProcessorTest {
1640970000000L, // 2022-01-01 01:00:00
1640973600000L, // 2022-01-01 02:00:00
1640977200000L, // 2022-01-01 03:00:00
- 1640980800000L // 2022-01-01 04:00:00
+ 1640980800000L, // 2022-01-01 04:00:00
+ 1640984400000L, // 2022-01-01 05:00:00
+ 1640988000000L // 2022-01-01 06:00:00
};
- final int[] expectedLevels = {100, 94, 90, 84, 56};
+ final int[] expectedLevels = {100, 94, 90, 84, 56, 98, 98};
assertThat(resultMap).hasSize(expectedLevels.length);
- for (int index = 0; index < expectedLevels.length; index++) {
+ for (int index = 0; index < 5; index++) {
assertThat(resultMap.get(expectedTimestamps[index]).get(FAKE_ENTRY_KEY).mBatteryLevel)
.isEqualTo(expectedLevels[index]);
}
+ for (int index = 5; index < 7; index++) {
+ assertThat(resultMap.get(expectedTimestamps[index]).containsKey(
+ DataProcessor.CURRENT_TIME_BATTERY_HISTORY_PLACEHOLDER)).isTrue();
+ }
}
@Test
@@ -188,6 +212,7 @@ public class DataProcessorTest {
final int[] levels = {100};
final Map> batteryHistoryMap =
createHistoryMap(timestamps, levels);
+ DataProcessor.sFakeCurrentTimeMillis = timestamps[timestamps.length - 1];
assertThat(
DataProcessor.getLevelDataThroughProcessedHistoryMap(mContext, batteryHistoryMap))
@@ -207,6 +232,7 @@ public class DataProcessorTest {
final int[] levels = {100, 94, 90, 82, 50};
final Map> batteryHistoryMap =
createHistoryMap(timestamps, levels);
+ DataProcessor.sFakeCurrentTimeMillis = timestamps[timestamps.length - 1];
final BatteryLevelData resultData =
DataProcessor.getLevelDataThroughProcessedHistoryMap(mContext, batteryHistoryMap);
@@ -239,6 +265,7 @@ public class DataProcessorTest {
final int[] levels = {100, 94, 90, 82};
final Map> batteryHistoryMap =
createHistoryMap(timestamps, levels);
+ DataProcessor.sFakeCurrentTimeMillis = timestamps[timestamps.length - 1];
final BatteryLevelData resultData =
DataProcessor.getLevelDataThroughProcessedHistoryMap(mContext, batteryHistoryMap);
@@ -290,8 +317,8 @@ public class DataProcessorTest {
@Test
public void getTimestampSlots_emptyRawList_returnEmptyList() {
- final List resultList =
- DataProcessor.getTimestampSlots(new ArrayList<>());
+ final List resultList = DataProcessor.getTimestampSlots(
+ new ArrayList<>(), 1641038400000L); // 2022-01-01 20:00:00
assertThat(resultList).isEmpty();
}
@@ -305,7 +332,7 @@ public class DataProcessorTest {
final Calendar expectedStartCalendar = Calendar.getInstance();
expectedStartCalendar.set(2022, 6, 5, 6, 0, 0); // 2022-07-05 06:00:00
final Calendar expectedEndCalendar = Calendar.getInstance();
- expectedEndCalendar.set(2022, 6, 5, 22, 0, 0); // 2022-07-05 22:00:00
+ expectedEndCalendar.set(2022, 6, 6, 0, 0, 0); // 2022-07-05 22:00:00
verifyExpectedTimestampSlots(
startCalendar, endCalendar, expectedStartCalendar, expectedEndCalendar);
}
@@ -320,7 +347,7 @@ public class DataProcessorTest {
final Calendar expectedStartCalendar = Calendar.getInstance();
expectedStartCalendar.set(2022, 6, 5, 6, 00, 00); // 2022-07-05 06:00:00
final Calendar expectedEndCalendar = Calendar.getInstance();
- expectedEndCalendar.set(2022, 6, 6, 20, 00, 00); // 2022-07-06 20:00:00
+ expectedEndCalendar.set(2022, 6, 6, 22, 00, 00); // 2022-07-06 20:00:00
verifyExpectedTimestampSlots(
startCalendar, endCalendar, expectedStartCalendar, expectedEndCalendar);
}
@@ -1110,8 +1137,8 @@ public class DataProcessorTest {
@Test
public void generateBatteryDiffData_emptyBatteryEntryList_returnNull() {
- assertThat(DataProcessor.generateBatteryDiffData(
- mContext, null, mBatteryUsageStats)).isNull();
+ assertThat(DataProcessor.generateBatteryDiffData(mContext,
+ DataProcessor.convertToBatteryHistEntry(null, mBatteryUsageStats))).isNull();
}
@Test
@@ -1161,8 +1188,8 @@ public class DataProcessorTest {
doReturn(BatteryConsumer.POWER_COMPONENT_CAMERA)
.when(mMockBatteryEntry4).getPowerComponentId();
- final BatteryDiffData batteryDiffData = DataProcessor.generateBatteryDiffData(
- mContext, batteryEntryList, mBatteryUsageStats);
+ final BatteryDiffData batteryDiffData = DataProcessor.generateBatteryDiffData(mContext,
+ DataProcessor.convertToBatteryHistEntry(batteryEntryList, mBatteryUsageStats));
assertBatteryDiffEntry(
batteryDiffData.getAppDiffEntryList().get(0), 0, /*uid=*/ 2L,
@@ -1284,16 +1311,15 @@ public class DataProcessorTest {
private static void verifyExpectedTimestampSlots(
final Calendar start,
- final Calendar end,
+ final Calendar current,
final Calendar expectedStart,
final Calendar expectedEnd) {
expectedStart.set(Calendar.MILLISECOND, 0);
expectedEnd.set(Calendar.MILLISECOND, 0);
final ArrayList timestampSlots = new ArrayList<>();
timestampSlots.add(start.getTimeInMillis());
- timestampSlots.add(end.getTimeInMillis());
final List resultList =
- DataProcessor.getTimestampSlots(timestampSlots);
+ DataProcessor.getTimestampSlots(timestampSlots, current.getTimeInMillis());
for (int index = 0; index < resultList.size(); index++) {
final long expectedTimestamp =