From b6b6ae4ef0f83728a8a9849a389b4449692c4292 Mon Sep 17 00:00:00 2001 From: Kuan Wang Date: Tue, 2 Aug 2022 13:57:32 +0800 Subject: [PATCH] Always do interpolation for battery level data in daily chart. Bug: 236101687 Test: make RunSettingsRoboTests Change-Id: I07ca512ceb7a74da4256f5d6fffed6d2432f89e0 --- .../fuelgauge/batteryusage/DataProcessor.java | 58 ++++++++++++++----- .../batteryusage/DataProcessorTest.java | 11 ++++ 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java index a004a519423..a51fbec73c1 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java @@ -218,7 +218,7 @@ public final class DataProcessor { * * 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 @@ public final class DataProcessor { } /** - * @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 @@ public final class DataProcessor { 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 @@ public final class DataProcessor { final long currentSlot, final List rawTimestampList, final Map> batteryHistoryMap, - final Map> resultMap) { + final Map> resultMap, + final boolean isStartOrEnd) { final long[] nearestTimestamps = findNearestTimestamp(rawTimestampList, currentSlot); final long lowerTimestamp = nearestTimestamps[0]; final long upperTimestamp = nearestTimestamps[1]; @@ -385,7 +398,8 @@ public final class DataProcessor { return; } interpolateHistoryForSlot(context, - currentSlot, lowerTimestamp, upperTimestamp, batteryHistoryMap, resultMap); + currentSlot, lowerTimestamp, upperTimestamp, batteryHistoryMap, resultMap, + isStartOrEnd); } private static void interpolateHistoryForSlot( @@ -394,7 +408,8 @@ public final class DataProcessor { final long lowerTimestamp, final long upperTimestamp, final Map> batteryHistoryMap, - final Map> resultMap) { + final Map> resultMap, + final boolean isStartOrEnd) { final Map lowerEntryDataMap = batteryHistoryMap.get(lowerTimestamp); final Map upperEntryDataMap = @@ -405,7 +420,10 @@ public final class DataProcessor { 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 @@ public final class DataProcessor { 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 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 1b1e469d1d9..af1030c9c67 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java @@ -401,6 +401,17 @@ public class DataProcessorTest { .isEqualTo(1640966400000L); } + @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 hourlyBatteryLevelsPerDay =