Always do interpolation for battery level data in daily chart.
Bug: 236101687
Test: make RunSettingsRoboTests
Change-Id: I07ca512ceb7a74da4256f5d6fffed6d2432f89e0
diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
index a004a51..a51fbec 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java
@@ -218,7 +218,7 @@
*
* The valid result should be composed of 3 parts:
* 1) start timestamp
- * 2) every 0am timestamp (default timezone) between the start and end
+ * 2) every 00:00 timestamp (default timezone) between the start and end
* 3) end timestamp
* Otherwise, returns an empty list.
*/
@@ -277,18 +277,27 @@
}
/**
- * @return Returns the timestamp for 0am 1 day after the given timestamp based on local
+ * @return Returns the timestamp for 00:00 1 day after the given timestamp based on local
* timezone.
*/
@VisibleForTesting
static long getTimestampOfNextDay(long timestamp) {
- final Calendar nextDayCalendar = Calendar.getInstance();
- nextDayCalendar.setTimeInMillis(timestamp);
- nextDayCalendar.add(Calendar.DAY_OF_YEAR, 1);
- nextDayCalendar.set(Calendar.HOUR_OF_DAY, 0);
- nextDayCalendar.set(Calendar.MINUTE, 0);
- nextDayCalendar.set(Calendar.SECOND, 0);
- return nextDayCalendar.getTimeInMillis();
+ return getTimestampWithDayDiff(timestamp, /*dayDiff=*/ 1);
+ }
+
+ /**
+ * Returns whether currentSlot will be used in daily chart.
+ */
+ @VisibleForTesting
+ static boolean isForDailyChart(final boolean isStartOrEnd, final long currentSlot) {
+ // The start and end timestamps will always be used in daily chart.
+ if (isStartOrEnd) {
+ return true;
+ }
+
+ // The timestamps for 00:00 will be used in daily chart.
+ final long startOfTheDay = getTimestampWithDayDiff(currentSlot, /*dayDiff=*/ 0);
+ return currentSlot == startOfTheDay;
}
/**
@@ -350,10 +359,13 @@
startIndex = 1;
resultMap.put(expectedStartTimestamp, batteryHistoryMap.get(rawStartTimestamp));
}
- for (int index = startIndex; index < expectedTimestampSlots.size(); index++) {
+ final int expectedTimestampSlotsSize = expectedTimestampSlots.size();
+ for (int index = startIndex; index < expectedTimestampSlotsSize; index++) {
final long currentSlot = expectedTimestampSlots.get(index);
+ final boolean isStartOrEnd = index == 0 || index == expectedTimestampSlotsSize - 1;
interpolateHistoryForSlot(
- context, currentSlot, rawTimestampList, batteryHistoryMap, resultMap);
+ context, currentSlot, rawTimestampList, batteryHistoryMap, resultMap,
+ isStartOrEnd);
}
}
@@ -362,7 +374,8 @@
final long currentSlot,
final List<Long> rawTimestampList,
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap,
- final Map<Long, Map<String, BatteryHistEntry>> resultMap) {
+ final Map<Long, Map<String, BatteryHistEntry>> resultMap,
+ final boolean isStartOrEnd) {
final long[] nearestTimestamps = findNearestTimestamp(rawTimestampList, currentSlot);
final long lowerTimestamp = nearestTimestamps[0];
final long upperTimestamp = nearestTimestamps[1];
@@ -385,7 +398,8 @@
return;
}
interpolateHistoryForSlot(context,
- currentSlot, lowerTimestamp, upperTimestamp, batteryHistoryMap, resultMap);
+ currentSlot, lowerTimestamp, upperTimestamp, batteryHistoryMap, resultMap,
+ isStartOrEnd);
}
private static void interpolateHistoryForSlot(
@@ -394,7 +408,8 @@
final long lowerTimestamp,
final long upperTimestamp,
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap,
- final Map<Long, Map<String, BatteryHistEntry>> resultMap) {
+ final Map<Long, Map<String, BatteryHistEntry>> resultMap,
+ final boolean isStartOrEnd) {
final Map<String, BatteryHistEntry> lowerEntryDataMap =
batteryHistoryMap.get(lowerTimestamp);
final Map<String, BatteryHistEntry> upperEntryDataMap =
@@ -405,7 +420,10 @@
final long upperEntryDataBootTimestamp =
upperEntryDataFirstEntry.mTimestamp - upperEntryDataFirstEntry.mBootTimestamp;
// Lower data is captured before upper data corresponding device is booting.
- if (lowerTimestamp < upperEntryDataBootTimestamp) {
+ // Skips the booting-specific logics and always does interpolation for daily chart level
+ // data.
+ if (lowerTimestamp < upperEntryDataBootTimestamp
+ && !isForDailyChart(isStartOrEnd, currentSlot)) {
// Provides an opportunity to force align the slot directly.
if ((upperTimestamp - currentSlot) < 10 * DateUtils.MINUTE_IN_MILLIS) {
log(context, "force align into the nearest slot", currentSlot, null);
@@ -877,6 +895,16 @@
return true;
}
+ private static long getTimestampWithDayDiff(final long timestamp, final int dayDiff) {
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(timestamp);
+ calendar.add(Calendar.DAY_OF_YEAR, dayDiff);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ return calendar.getTimeInMillis();
+ }
+
private static boolean contains(String target, Set<CharSequence> packageNames) {
if (target != null && packageNames != null) {
for (CharSequence packageName : packageNames) {
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 1b1e469..af1030c 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java
@@ -402,6 +402,17 @@
}
@Test
+ public void isForDailyChart_returnExpectedResult() {
+ assertThat(DataProcessor.isForDailyChart(/*isStartOrEnd=*/ true, 0L)).isTrue();
+ // 2022-01-01 00:00:00
+ assertThat(DataProcessor.isForDailyChart(/*isStartOrEnd=*/ false, 1640966400000L))
+ .isTrue();
+ // 2022-01-01 01:00:05
+ assertThat(DataProcessor.isForDailyChart(/*isStartOrEnd=*/ false, 1640970005000L))
+ .isFalse();
+ }
+
+ @Test
public void getBatteryUsageMap_emptyHistoryMap_returnNull() {
final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay =
new ArrayList<>();